Devi almeno implementare il conteggio dei tentativi a livello di account e per IP, in modo che il blocco delle password sia bloccato indipendentemente dal fatto che si tratti di un account e di molte password o di molti account e alcune password comuni.
Il modo migliore per eseguire il conteggio è registrare i tentativi su una tabella di database, quindi calcolare il conteggio in fase di esecuzione utilizzando una query. È possibile utilizzare una serie di query come questa per calcolare i conteggi:
// get the last successful login time.
// if this returns no rows, default it to 2000-01-01 00:00:00 or similar
SELECT TOP(1) attempt_time AS last_success_time
FROM login_attempts
WHERE success = 0
SELECT MAX(tmp.attempt_count) AS attempt_count // we want the highest count
FROM (
SELECT COUNT(*) AS attempt_count
FROM login_attempts
WHERE
attempt_time > $last_success_time // only count from the last successful login
and success = 0
and ip_address = $ip; // count by IP
UNION
SELECT COUNT(*) AS attempt_count
FROM login_attempts
WHERE
attempt_time > $last_success_time // only count from the last successful login
and success = 0
and user_id = $uid; // count by user ID
) tmp;
Un'altra cosa a cui prestare attenzione sono i proxy. La maggior parte delle persone si preoccupa di loro e tenta di utilizzare intestazioni come X-Forwarded-For
per bloccare gli IP di origine. Il problema con questo è che X-Forwarded-For
può essere impostato da un utente malintenzionato e utilizzato per ottenere l'indirizzo IP bannato, semplicemente non riuscendo ad accedere. Come tale, dovresti controllare i divieti esistenti in base a X-Forwarded-For
e l'IP di origine, ma non impostare mai nuovi divieti in base all'intestazione. Ciò significa che gli utenti che tentano di eludere i divi utilizzando un proxy verranno catturati se il proxy fornisce X-Forwarded-For
, ma gli autori degli attacchi non possono contraffarli tramite esso. Ha anche l'effetto collaterale di bandire i proxy che vengono usati per gli attacchi, il che è un bel bonus.