Qual è il metodo migliore per prevenire un attacco di forza bruta?

Ho la mia pagina di accesso e, naturalmente, voglio prevenire gli attacchi di forza bruta e causare less ritardo agli utenti quando effettuano l'accesso.

Attualmente, si digita il nome utente e la password per accedere.

Sto considerando l'implementazione di un reCAPTCHA . Tuttavia, questo mostra al login dopo 3 tentativi falliti.

La mia domanda è:

  1. Su cosa si basa il tentativo. Indirizzi IP? Può sempre essere nascosto … username? Cosa succede se stanno provando un utente che non esiste?

  2. Quale sarebbe il metodo migliore per contare i tentativi di accesso falliti?

Le sessioni non sono affidabili perché si basano sui cookie, i CAPTCHA sono regolarmente interrotti [incluso ReCAPTCHA]. L'unico metodo affidabile è ingannevolmente semplice: fai una domanda. Non usare una domanda math perché i computer sono sorprendentemente abili a risolvere quelli per qualche motivo. I grandi vecchi standbys sono cose come:

  • Qual è la quarta parola del sesto paragrafo in questa pagina ?
  • Qual è il nome dell'autore di questo sito? [suggerimento]

È stupido, facile da implementare e molto difficile da risolvere per una macchina.

Per quanto riguarda il bute-forcing, prova ad aggiungere due campi alla tabella utente, 'first_failed_login' [ INTEGER unix timestamp o DATETIME ] e 'failed_login_count'. [ INTEGER ]

 <?php $bad_login_limit = 3; $lockout_time = 600; $first_failed_login, failed_login_count; // retrieve from DB if( ($failed_login_count >= $bad_login_limit) && (time() - $first_failed_login < $lockout_time) ) { echo "You are currently locked out."; exit; // or return, or whatever. } else if( /* login is invalid */ ) { if( time() - $first_failed_login > $lockout_time ) { // first unsuccessful login since $lockout_time on the last one expired $first_failed_login = time(); // commit to DB $failed_login_count = 1; // commit to db } else { $failed_login_count++; // commit to db. } exit; // or return, or whatever. } else { // user is not currently locked out, and the login is valid. // do stuff } 

In questo modo il tuo sistema di login riconoscerà solo 3 tentativi di accesso per utente each 10 minuti.

Non fare affidamento su sessioni o cookie, quelli si fidano del client e non devi MAI fidarti del client. Ho creato una class che si occupa della protezione da attacchi di forza bruta in PHP.

https://github.com/ejfrancis/BruteForceBlocker

registra tutti gli accessi non riusciti a livello di sito in una tabella db e se il numero di accessi non riusciti negli ultimi 10 minuti (o in qualsiasi intervallo di tempo selezionato) supera un limite impostato, impone un ritardo temporale e / o un requisito captcha prima di accedere di nuovo.

esempio:

  //build throttle settings arrays. (# recent failed logins => response). $throttle_settings = [ 50 => 2, //delay in seconds 150 => 4, //delay in seconds 300 => 'captcha' //captcha ]; $BFBresponse = BruteForceBlocker::getLoginStatus($throttle_settings); //$throttle_settings is an optional parameter. if it's not included,the default settings arrays in BruteForceBlocker.php will be used switch ($BFBresponse['status']){ case 'safe': //safe to login break; case 'error': //error occured. get message $error_message = $BFBresponse['message']; break; case 'delay': //time delay required before next login $remaining_delay_in_seconds = $BFBresponse['message']; break; case 'captcha': //captcha required break; } 

Cerca di verificare che tu abbia a che fare con un vero browser. Forse alcune brutte sfide con script java con nomi di funzioni casuali o qualcosa potrebbero bloccare un sacco di semplici script, a less che non controllino a distanza un browser reale (cosa non rara), o valutino correttamente js / css nello script raschietto.

Consiglierei di leggere oltre su questo argomento e testare la tua soluzione contro Python Mechanize o altri strumenti di raschiatura ben noti.

Ma uno è sicuro, non esiste una soluzione reale contro gli attacchi automatici.