Throttling tentativi di accesso falliti: timeout esponenziale? per IP? usando un cookie di sessione? captcha?

7

Sto iniziando a pensare che non è così semplice come sembra, e molte risposte "accettate" qui e in SO hanno risposte alternative che li criticano. Ecco cosa ho raccolto finora

La maggior parte di ciò che ho raccolto proviene da questa domanda SO

Utilizzo di IP - non accurato

For ex. in countries like Singapore there are limited number of ISPs and a smaller set of IPs which are available for home users

Inoltre, penso che questo non sia efficace negli attacchi brute force distribuiti

Uso del cookie di sessione - facile da superare, non richiede molto tempo per cancellare un cookie e non è efficace negli attacchi di forza bruta distribuiti

L'utilizzo del nome utente - timeout esponenziale crescente - può avere soluzioni alternative

If I have a list of 1000 usernames, I'll try user1+password1, user2+pasword1, user3+password1... user1+password2, user2+password2

Utilizzo di ricapitolazione - buona, ma devi ancora sapere che è lo stesso "utente" (che può fare un attacco distribuito, cancellare i cookie, ecc.)

Quindi presumo che non esista una soluzione perfetta, ma esiste una soluzione "buona" approccata da qualsiasi organizzazione come OWASP per la gestione della limitazione dei tentativi di accesso falliti?

    
posta Eran Medan 21.11.2012 - 02:42
fonte

4 risposte

5

Una volta ho considerato l'utilizzo di un approccio simile a Puzzle di Merkle . Ad esempio, potresti richiedere che ogni tentativo di accesso venga firmato con HMAC utilizzando una sola volta. Ad esempio, il server potrebbe preparare il puzzle nel seguente modo: - seme (valore casuale lungo), - r (valore intero casuale all'interno di un intervallo arbitrario), - chiave = PBKDF2 (seed, r)

Il server potrebbe inviare il seguente puzzle al client: (seed, hash (chiave)). Per ottenere una chiave valida, il client dovrebbe forzare questo puzzle (controllare i valori sequenzialmente r, calcolare PBKDF2 per un dato seme, confrontare il suo hash con l'hash (chiave) ricevuto dal server). Quando il client trova la chiave corretta, la utilizza per firmare un tentativo di accesso.

In questo approccio la quantità di lavoro è asimmetrica tra client e server (il cliente deve fare più calcoli). Inoltre, il server può regolare il "fattore di lavoro" modificando l'intervallo dal valore della strega r selezionato.

Ovviamente questo schema non impedirebbe la forzatura bruta della password, ma aumenterebbe il costo di tale attacco.

Come ho detto è solo un'idea approssimativa, non sono sicuro di quanto possa funzionare in pratica.

    
risposta data 21.11.2012 - 07:42
fonte
3

Per proteggersi dalla rottura bruta della password, dovresti usare essenzialmente ciò che definisci " Usando il nome utente - timeout esponenziale crescente ". Per ogni nome utente, tenere un conteggio dei guasti dall'ultimo accesso riuscito e un valore temporale per quando sarà consentito un altro tentativo di accesso. Prima di verificare la password inviata, confronta l'ora corrente con il tempo di blocco del nome utente. Se l'ora non è ancora avvenuta, evitare che la richiesta di accesso proceda. Puoi farlo ritardando la richiesta, ma se sono consentiti troppi ritardi (che occupano le risorse del server), sarai facilmente soggetto a un attacco DDOS. Quindi, invece, rispondi con lo stato http 429 Troppe richieste quando il lock-out non è scaduto sul nome utente. Ogni volta che un accesso è autorizzato a procedere oltre, e quindi la password non riesce, il conteggio errori del nome utente viene incrementato e in base a questo il tempo di blocco viene impostato sull'ora corrente più il ritardo esponenziale basato sul conteggio errori. Un accesso riuscito reimposta il conteggio errori e il tempo di blocco.

La "soluzione alternativa" che mostri non è particolarmente problematica. Sia che la lista di 1000 nomi utente venga provata in sequenza o in parallelo, ciascuno dei nomi utente avrà il proprio tempo di lock-out mantenuto, e dopo alcuni round per ciascuno, ognuno impedirà una rapida manutenzione dei tentativi di forzatura bruta.

    
risposta data 22.11.2012 - 08:51
fonte
2

Con "throttle" presumo che intendi che visualizzi immediatamente una pagina web (con qualsiasi quantità di funzionalità) o un errore 5xx, giusto? (contrariamente al semplice invio della pagina di accesso più lentamente .. con un timer sleep ())

Forse puoi usare un approccio ibrido di pesi positivi e negativi. Lo uso per gestire lo spam delle e-mail e forse alcune lezioni apprese possono essere condivise qui.

Per iniziare, traccia tutti i dati che hai elencato sopra per gli accessi riusciti e falliti. Quindi assegnare un "livello di confidenza" compreso tra 10 positivi e 10 negativi in ciascuna variabile.

Quindi, quando l'utente tenta di accedere, puoi semplicemente calcolare il rapporto degli accessi riusciti con gli accessi non riusciti e pesarlo per il livello di confidenza (moltiplica). Sommare il risultato e utilizzarlo per determinare il grado di limitazione della sessione.

Nota l' impronta digitale del browser e imposta un cookie all'accesso corretto, e per ogni tentativo di accesso potrebbe essere utile anche a te in questo tentativo .

Sono sicuro che i desktop aziendali, i consumatori generici e il pubblico internazionale creerebbero profili molto distinti che peserebbero ciascun valore in modo diverso. Sarei interessato a saperne di più sul tuo progetto, i tuoi pensieri e ciò che stai facendo.

P.S. Ogni volta che eseguo qualsiasi calcolo con una pagina di accesso, mi assicuro di utilizzare sempre un tempo fisso per il calcolo (500 ms). Ciò consentirà di evitare che gli Orsi di Crittografia si insinuino e che abbiano storicamente afflitto tali pagine.

P.P.S Quando crei la pagina di accesso, assicurati di non bloccare i thread con le operazioni di ritardo (come sleep ()), altrimenti questo renderà DDOS il tuo server rapidamente. In alternativa, restituisci alcuni errori HTML o 500 all'utente interessato.

    
risposta data 21.11.2012 - 06:39
fonte
1

Sto usando un OTP - significa che i miei accessi sono basati su tre chiavi distinte:

  • nome utente
  • Password
  • OTP (password una tantum) fornita da yubikeys.

Ho anche aggiunto, per un'app, un contatore - se X ha avuto esito negativo sugli accessi in un dato intervallo, esso:

  • reindirizza ad una pagina di errore (costringendo le persone a fare clic su qualche link per l'accesso - inutile per i bot)
  • blocca l'account dopo diversi tentativi.

Il blocco può essere basato sull'IP remoto per evitare falsi positivi.

    
risposta data 22.11.2012 - 08:11
fonte

Leggi altre domande sui tag