A (security) bug’s life

Il vero cancro sono i siti tipo squarespace.

Quelli si che sono una merda incredibile e pensati solo per inchiodarti nel loro prodotto di merda e farti pagare la tua subscription.

Mah io continuo a non vederne molto il senso pure in quei casi.
Un CMS headless di nuova generazione piu’ una generazione statica per 80% delle persone basta e avanza per avere la dinamicita’ / self-serve offerti da un CMS mantenendo semplicita’ di deploy che si trasforma in costo ridotto e scalabilita’ “infinita”.
Il problema e’ che una roba del genere l’agenzia non te lo propone perche’ si tratta di “one time setup” piuttosto che un modello di supporto continuo “il tuo wordpress ha bisogno di manutenzione costante o ti entra il primo hacker pakistano”.

Il rimanente 20% di casi molto piu’ complessi ci sono una miriade di soluzioni a partire da ISR incremental static generation che mantiene di nuovo i costi bassi fino ad arrivare a soluzioni piu’ complesse, che pero’ realisticamente toccano forse il 5% dei casi a dir tanto e dove wordpress non e’ decisamente la cosa giusta.

poi la realta’ purtroppo e’ un altra, ci sono siti enormi fatti in wordpress ma perche’

If the only tool you have is a hammer, you tend to see every problem as a nail.

Pienamente d’accordo qui :approved: pero’ “funziona” perche’ cmq ci sono tante persone che non vogliono sbatti, pagano 10 euro al mese e hanno il sito online, purtroppo sono dolori poi quando vogliono migrare o fare qualcosa di leggermente piu custom di quel (poco) che offre la piattaforma

1 Like

Jekyll e Hugo :love:

1 Like

Not really. Tieni in conto che normalmente le aziende che avviano un programma di bug bounty gia’ hanno un security team interno e usano vari scanners, quindi usare gli stessi e’ giusto un tiro alla fortuna. Per questo motivo di solito non uso neanche Nuclei a meno che e’ un programma iniziato proprio adesso.

1 Like

BTW ho trovato altri tree vulnerabilita’ :D I’m on a roll.

Quindi sono 5 in 2 giorni ma per ora ne ho riportate soltanto 3, perche’ due sono difficili da usare e voglio spendere sopra un po’ piu’ di tempo.

Le altre 3 vulnerabilita’ sono

  • un’altra race condition, che pero’ questa volta mi consente di create molte subscriptions con lo stesso account usando un singolo voucher; non l’ho riportata perche’ non sono riuscito a controllare la start date della subscription e dunque tutte quelle che creo hanno la stessa expiration. Dunque devo trovare un modo, se c’e’, per controllare quando ogni subscription comincia effettivamente. Ho gia’ un’idea per questo ma ho bisogno di piu’ tempo e una volta preparata la cosa dovro’ aspettare un mese prima di continuare (cioe’ devo aspettare che la prima subscription scade)

  • una IDOR (insecure direct object reference): l’acquisto di una subscription avviene in due fasi: la prima richiede il pagamento o un voucher, e la seconda la conferma che poi attiva la subscription. Ho trovato un modo per attivare nel mio account un ordine preparato da un altra persona, e quindi tecnicamente posso “rubare” la loro subscription. Il problema e’ che mi serve l’order id, e siccome sono difficili da indovinare, sono un po’ bloccato e dunque non l’ho ancora riportato.

  • un improper access control che mi consente di bypassare il PIN per accedere a tutto il catalogo mentre si usa un profilo restricted per bambini. In pratica l’account owner puo’ creare un PIN per non consentire ad un bambino di cambiare il profilo, ma ho trovato un modo per cancellare il PIN facilmente ed accedere a tutto il catalogo quando sono in un profilo per bambini. Anche se’ e’ una vulnerabilitta’ tecnicamente, praticamente richiede il bambino di essere abbastanza sveglio :rofl: Quindi non so’ cosa diranno ma l’ho riportata perche’ e’ comunque una vulnerabilita’ in access control.

4 Likes

Da pentester sei anche bravo a creare sistemi sicuri oppure sono skill simili ma non correlate?

Forse e’ un po confusa la domanda: intendo dire se per lavoro fai o hai fatto in passato architettura di sistemi sicuri, e mi domando se le skill che ha un pentester identiche a quelle che ha chi si occupa di creare sistemi, piu che di bucarli.

Immagino ci sia un grosso overlap tra le due cose ma mi verrebbe da dire che nn e’ necessariamente 100% e ci sia una specializzazione cmq richiesta in entrambe le aree?

Sono dev da quasi 30 anni :slight_smile:

BB e’ nel mio tempo libero, ma al day job sono lead architect ovviamente gestisco lo sviluppo non solo la sicurezza. E’ soprattutto grazie al fatto che sono dev da cosi’ a lungo e ho lavorato su sistemi di tutti i tipi e dimensioni, se me la cavo bene con bb. :)

2 Likes

Ottimo :smile:

Sto creando un servizio, ti va se spiego qui in modo astratto e mi dai un tuo parere sulla sicurezza che ho in mente? (qui in pubblico ovviamente non in privato cosi che se altri vogliono contribuire possono)

Certo!

Sto costruendo un sistema di “cache remota as a service”

Premessa

L’use case e’ quando hai un monorepo ammettiamo con 5 apps e 3 package condivisi, dove per ognuno vuoi fare andare dei test e compilare l’app, ti ritrovi con 532 = 30 task da eseguire in CI.
Normalmente senza particolari setup in CI ogni volta che tu cambi una riga di codice, tutti i task vengono rifatti.
Questo e’ ovviamente un processo molto inefficiente che rende le build molto piu lente di quel che dovrebbero peggiorando DX ma soprattutto usando un sacco di risorse in piu = soldi spesi dall’azienda, che a seconda della dimensione possono essere qualche migliaia di euro o qualche milione all’anno :asd:
Google che e’ notoriamente costruita su monorepo gigaenormi ha dovuto risolvere questo problema e mille anni fa e ha creato https://bazel.build/ dove sostanzialmente si introduce un caching layer che funziona basandosi su una descrizione delle dipendenze (un grafo), hashing degli input per capire cosa cambia e storage (cache) degli output.

Il motto di questo sistema e’ sostanzialmente “non fare due volte lo stesso lavoro”.

Ultra semplificando il sistema ha 2 API

  • la prima volta che un task viene completato salvare l’output (artifact) in una cache
  • la seonda volta chiedere alla cache di pescare l’artifact senza cosi bisogno di ricomputarlo

Nel mio sistema multi tenant ogni tenant si sceglie un username e io gli genero un token.
Le API saranno protette dalla combinazione di username + token.
L’username mi serve per segregare i file cached, dove prevedo una struttura tipo questa immaginando che io e te siamo due tenant.

/cache/SkyLinx/* # tuoi file
/cache/mtt/*  # miei file

username+token sono salvati su DB al momento un sqlite su un volume persistent attaccato al pod’ che mantiene semplicita’ e velocita’ (no network calls)

possiamo assumere che il cluster kubernetes e’ in totale sicurezza e non ha accesso pubblico, e’ solo ad uso interno e solo io ho accesso al namespace e relativo volume.

il servizio che gira nel pod non ha permessi root e solo quel servizio ha accesso a poter leggere lo storage.

tecnicamente dovrei fare un hash del token cosi da non salvarlo in chiaro, ma questo viene a spese di una peggiore DX in quanto vuol dire che posso mostrare il token solamente una volta all’utente e poi se lo deve salvare. per il momento ho preferito avere una migliore DX a scapito un po della sicurezza su questo fronte, fatte cmq le premesse sopra che il contorno e’ molto sicuro e sono solo io ad avere accesso e l’unico vettore di attacco e’ sostanzialmente il mio laptop aziendale.

lato consumatore voglio assicurarmi dell’autenticita’ e dell’integrita’ dei miei file, aka assicurarmi che nessuno abbia fatto tampering.
per questo da consumatore posso fare sign con hmac-sha256 con una chiave che ho solo lato consumatore quando carico l’artifact e verificare poi quando riprendo l’artifact che mi viene rimandato indietro

lato storage devo assicurarmi che nessuno possa accedere ai file di qualcun altro, e al momento la logica dipende solo dalla mia app che legge username+token dal DB e verifica che c’e’ un match e quindi permette di leggere dalla cartella /cache/username pero’ a lungo termine non e’ una soluzione strong.
qui non sono sicuro di cosa sia una buona scelta che possa aumentare la sicurezza senza pero’ aumentare la complessita’ di utilizzo peggiorando DX.

che ne pensi?

Aspettiamo skylinx per vedere cosa ne pensa ma in generale piu’ frammenti e oscuri la chiave e meglio e’. Il discorso di farla vedere solo in creazione imho e’ la via giusta ma finche’ sei ancora in fase di exploration/experimentation ci sta come stai andando imho.

Qui un video di Maya Kaczorowski (ogni volta devo copiare e incollare il cognome cazzo). E’ una grandissima che ho conosciuto al google next del 2017 che fecero a Londra.

Qui spiega come gestiscono la sicurezza delle chiavi at rest a google in breve (2 minuti) e piu’ a lungo durante la presentazione del 2017

1 Like

Visto quello breve, bello tosto si :asdlode: ma si entra in un territorio molto complesso quando cominciano a girare varie chiavi, dove tenerle, come usarle, fare rotation, che e’ molto lontano dalla mia expertise.

Al momento ci sta lavorando full time il summer intern e io nel tempo libero, tipo ora xke mi appassiona il progetto.

Siamo ben lontani dall’avere quella necessita’ ma arrivare al momento in cui si rende necessario beh sarebbe un enorme win per noi :omg: perche’ vuol dire che tanti team vogliono usare il servizio, a quel punto (o appena e’ possibile) probabilmente cercheremo di portare dentro qualcuno che puo’ contribuire con quelle specifiche skill, l’importante e’ che facciamo trovare qualcosa che ha delle buone fondamenta e che poi si puo’ migliorare.

Al momento c’e’ parecchia roba da costruire di contorno al core che fa il servizio.
Ad esempio devo aggiungere logica per registrare tutto il tempo risparmiato cosi da poter avere poi dei dati da sbattere sul tavolo quando arrivera’ il momento :teach:

Avevo cominciato questo progetto intorno a marzo per imparare rust e alla fine mi sta piacendo quindi mi ritrovo qui venerdi sera mentre guardo un po le olimpiadi a portarlo avanti :asdsad:

1 Like

È un idea molto figa comunque, anche solo come sfida tecnica, nel malaugurato caso che non trovi mercato. Veramente figa :lode:

1 Like

Domanda sulla premessa: perche’ non avere workflow diversi, ognuno che fa una cosa con triggers opportuni, invece di eseguire tutti i task ogni volta?

Alcune note a caso:

  • mai salvare tokens in chiaro nel database. Se non vuoi usare una hash perche’ vuoi essere in grado di mostrare i token all’utente nella UI, allora cripta i token at rest almeno. Anche il cluster lo ritieni “sicuro” (potrei dirti molte storie dove sono riuscito ad accedere a control plane e bypassare RBAC etc anche con cluster privati e non esposti direttamente ad internet, grazie a vulnerabilita’ nelle app) basta una piccola SQLi in un applicazione esposta ad utenti, per poter potenzialmente compromettere i token. Non rischierei. Come @crius diceva e’ sempre meglio comunque non salvare i token in un modo che possono essere ricostruiti. Se opti per criptare i dati, considera un sistema DEK+KEK, con DEK derivata da qualcosa unico all’utente.
  • invece di HMAC-SHA256 potresti optare per qualcosa di veloce come Blake2, che andrebbero meglio anche con file piu’ grandi
  • storage: per come lo descrivi, se un attacker riesce a trovare username e qualche vulnerabilita’ che consente di fare escape dal container (non so come si dice in italiano), allora hai un problema.
  • Sembra che hai intenzione di mettere tutto in subdirectories di /cache. Questo significa che nel caso di una vulnerabilita’ path traversal un attacker potrebbe accedere a file di altri utenti se non c’e’ un metodo di autorizzazione e ACL a livello di file system/storage stesso
  • poi mi chiedo se sqlite e’ una scelta buona… tieni presente scalabilita’ e backup tra le varie cose

Se puoi condividere piu’ dettagli posso farmi una idea migliore di cosa hai in mente. Inoltre visto che e’ su Kubernetes, che tipo di storage hai in mente? Perche’ soluzioni come si deve dipendono anche da questo

Uhm rileggendo forse non ho capito bene. Hai intenzione di criptare i file oppure no? Puoi chiarire :)

Ti rispondo domani con calma, sto tornando a casa ora sono dal cel :smiley:

Sure

Tra questo e salvare un hash a questo punto vado di hash e mostro il token una sola volta.
Cryptare i dati aggiunge troppa complessita’ in questa fase MVP del progetto.

Questo non posso cambiarlo purtroppo in quanto non ho diretto controllo sul CLI usato in CI che adotta questo algoritmo per la signature.

Non sono sicuro di capire, cosa intendi per “escape dal container” in questo contesto?
C’e’ un cluster vuoto con solo 1 pod il cui container e’ probabilmente basato su un rhel minimal dove c’e’ solo il processo del mio servizio e nient’altro running, e c’e’ un persistent storage che viene montato in una directory ogni volta che il pod viene creato/ricreato.
In questo contesto non sono sicuro cosa possa fare un attacco di tipo “escape dal container” non ci sarebbe niente penso?

Questo e’ interessante ci ho pensato e al momento ho solo messo questa piccola protezione in place

// to prevent directory traversal attacks
// we ensure the path consists of exactly one normal component
fn path_is_valid(path: &str) -> bool {
    let path = std::path::Path::new(path);
    let mut components = path.components().peekable();

    if let Some(first) = components.peek() {
        if !matches!(first, std::path::Component::Normal(_)) {
            return false;
        }
    }

    components.count() == 1
}

Pensando sempre in un ottica MVP, dove devo trovare un buon compromesso tra rilasciare il prodotto nel breve tempo con il giusto compromesso di sicurezza vs renderlo estremamente sicuro ma lanciarlo tra 1 anno, c’e’ qualche “quick win” qui che posso fare senza spendere troppo tempo?

pro: essendo un file sullo stesso volume, non ci sono network calls e dipendenze da un servizio esterno che potrebbe essere down, non c’e’ da gestire rotazione di credenziali e quant’altro.

contro: non c’e’ backup

lato scalabilita’ sqlite puo’ scalare ben oltre quello che le persone pensano, stiamo parlando cmq di un servizio che se va bene verra’ usato da centinaia di team, non migliaia/milioni.
https://www.sqlite.org/whentouse.html

The SQLite website (https://www.sqlite.org/) uses SQLite itself, of course, and as of this writing (2015) it handles about 400K to 500K HTTP requests per day, about 15-20% of which are dynamic pages touching the database. Dynamic content uses about 200 SQL statements per webpage. This setup runs on a single VM that shares a physical server with 23 others and yet still keeps the load average below 0.1 most of the time.

Sul cluster non ho controllo, mi viene fornito con delle quote e messo in sicurezza.
Idem storage, nel mio manifest devo solo chiedere un persistent volume claim e lo spazio richiesto.
Che altri dettagli possono servirti? Non saprei mi e’ sembrato di essere stato molto dettagliato :smile:

Si’, e’ molto piu’ semplice infatti

Capisco. Va bene, l’unica cosa e’ che e’ un po’ lento

In alcuni casi e’ possibile “uscire” dal contesto del container e accedere all’host. Non e’ semplice ma e’ spesso possibile.

Se usi un minimal os con attack surface piccola e’ decisamente piu’ diffcile.

Non conosco Rust ma tieni presente che molte librerie e file systems fanno “normalizzazione” dei path, quindi ci’ potrebbe essere un modo per bypassare controlli. Ma non conosco Rust quindi non so se e’ robusto.

Ma cosi’ puoi solo avere un pod che accede al volume se e’ block storage e quindi c’e’ downtime quando il pod viene rescheduled. O stai usando qualcosa come NFS?

E’ managed or on prem?

Si al momento penso sia una limitazione che ho e da quel che ho capito il volume che mi offre il sistema è possible montarlo solo su un pod non multipli.
Downtime è accettabile in questa fase, in futuro per scalare il sistema ho la possibilità di usare uno storage simile a s3 ma interno, così da non avere queste limitazioni e avere anche più pods se necessario

In questo caso dal mio punto di vista di “developer consumatore” è managed, io applico solo il manifest della mia app e il resto non tocco niente, però gira su data center nostro non cloud pubblici