Per evitare BREACH, possiamo utilizzare gzip su risposte non token?

4

Lavoro su un sito che ha un'interfaccia web e un'API. Sto provando a determinare se possiamo usare tranquillamente gzip o se questo ci aprirà a BREACH .

Il sito dice:

If you have an HTTP response body that meets all the following conditions, you might be vulnerable:

  • Compression: Your page is served with HTTP compression enabled (GZIP / DEFLATE)
  • User Data: Your page reflects user data via query string parameters, POST..
  • A Secret: Your application page serves PII, a CSRF token, sensitive data...

Un altro sito dice:

It requires the attacker to be able to read the size of encrypted traffic and perform CSRF requests at will

Utilizziamo un framework Web che aggiunge automaticamente un token CSRF mascherato (diverso ogni volta) a ogni modulo che utilizza POST .

Abbiamo pagine (es. risultati di ricerca) che riflettono l'input dell'utente, ma non contengono dati sensibili (il modulo per la ricerca utilizza GET ).

Abbiamo un endpoint API che serve un token API, ma ogni volta ha un valore diverso perché è crittografato con un timestamp.

La maggior parte delle nostre risposte sono corpi JSON di grandi dimensioni che trarrebbero molto vantaggio da gzip.

Possiamo attivare gzip ovunque? È sufficiente disattivarlo quando si risponde con un token API ? O possiamo semplicemente non avere cose belle?

    
posta Nathan Long 31.10.2017 - 21:00
fonte

1 risposta

5

Sto rispondendo alla mia stessa domanda perché credo ora capisco BREAK e come prevenirlo. Mi piacerebbe un feedback.

Funzionamento di BREACH (a quanto ho capito)

(Espansione su una spiegazione qui che mi ha aiutato.)

Supponi di essere un attaccante. Hai effettuato l'accesso a un servizio come te stesso. Si nota che esiste un endpoint search e se si invia il termine di ricerca rabbits , si ottiene una risposta come questa:

<SearchResponse>
  <AuthToken>d2a372efa35aab29028c49d71f56789</AuthToken>
  <SearchTerm>rabbits</SearchTerm>
  <Results>
    <Result>rabbits rock</Result>
    <Result>yay rabbits</Result>
  </Results>
</SearchResponse>

Noterai anche che la risposta è gzip e crittografata (HTTPS).

Prova a cercare una stringa formattata come <AuthToken , come aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa . La risposta è:

<SearchResponse>
  <AuthToken>d2a372efa35aab29028c49d71f56789</AuthToken>
  <SearchTerm>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</SearchTerm>
  <Results>
  </Results>
</SearchResponse>

Non ci sono risultati per questo. Quindi modifica leggermente il termine di ricerca:

<SearchResponse>
  <AuthToken>d2a372efa35aab29028c49d71f56789</AuthToken>
  <SearchTerm>d2a37aaaaaaaaaaaaaaaaaaaaaaaaaa</SearchTerm>
  <Results>
  </Results>
</SearchResponse>

Come speravi, sta accadendo qualcosa di interessante. Poiché il termine di ricerca non ha senso, <Results> è sempre lo stesso: vuoto. L'unica cosa chaing è <SearchTerm> . A causa della compressione, più il valore <SearchTerm> assomiglia al valore <AuthToken> , più piccola è la risposta.

Questo è il modo in cui funziona la compressione gzip: rimuove la ripetizione durante la compressione e la ripristina durante la decompressione. Più l'input è ripetitivo, più piccolo viene compresso.

Cerca di nuovo, utilizzando il valore esatto di <AuthToken> .

<SearchResponse>
  <AuthToken>d2a372efa35aab29028c49d71f56789</AuthToken>
  <SearchTerm>d2a372efa35aab29028c49d71f56789</SearchTerm>
  <Results>
  </Results>
</SearchResponse>

Questa volta prendi nota di quanto sia piccola la risposta.

Ora, poiché queste sono le tue richieste, sei stato in grado di leggerle direttamente. Se si potesse fare un attacco MITM su un altro utente del sito (ad esempio, eseguendo un router canaglia), si sarebbe in grado di vedere la dimensione della risposta crittografata, ma non i contenuti effettivi.

Pensi a te stesso: se posso ingannare qualcun altro nell'invio dei termini di ricerca li voglio, e se riesco a vedere quanto è grande la risposta crittografata, posso modificare il termine di ricerca più e più volte. Più mi avvicino a indovinare il token auth, più piccola sarà la risposta, e quando è la dimensione della risposta che ho appena visto, ho indovinato correttamente. Una volta che conosco il loro token di autenticazione, posso accedere come loro.

Se puoi in qualche modo eseguire un attacco XSS sulla tua vittima, puoi farli fare le richieste necessarie.

Mitigazione

Questo attacco non funzionerebbe se:

  • Il server non ha utilizzato la compressione HTTP (come gzip, nel nostro esempio)
  • La richiesta non può essere eseguita correttamente senza un token CSRF, che l'utente malintenzionato non può sapere
  • Il server non inserisce mai entrambi dati sensibili (come un token API) e dati forniti dall'utente (come il termine di ricerca) nella stessa risposta
  • Il server non ha mai restituito lo stesso token dell'API due volte (ad esempio, se i valori dei token grezzi sono stati timestampati e firmati prima dell'invio, il timestamp garantisce che il token nella risposta sia costantemente modificato)
  • La risposta conteneva sempre un riempimento a caso, come indicato da @AndrolGenhald in un commento (sebbene con richieste sufficienti, un utente malintenzionato potrebbe separare il segnale da questo rumore)
risposta data 01.11.2017 - 15:26
fonte

Leggi altre domande sui tag