Update: Verwenden Sie nicht sleep() für die Begrenzung der Geschwindigkeit! das macht überhaupt keinen Sinn. Ich habe keine bessere Lösung zur Hand.
wäre ein guter Anfang nur sleep(1);
nach einem gescheiterten Login-Versuch sein - einfach, fast fehlerfrei zu implementieren.
1 Sekunde ist nicht viel für einen Menschen (vor allem, weil Login-Versuche von Menschen nicht oft versagen), aber 1sec/versuchen Brute-Force ... sloooow! Wörterbuchangriffe können ein anderes Problem sein, aber es ist in der gleichen Domäne.
Wenn der Angreifer auch startet, können Verbindungen, um dies zu umgehen, Sie befassen sich mit einer Art DOS-Angriff. Problem gelöst (aber jetzt hast du ein anderes Problem).
einige Dinge, die Sie berücksichtigen sollten:
- wenn Sie Konten soley auf einer pro IP-Basis zu sperren, kann es zu Problemen mit privaten Netzwerken sein.
- wenn Sie Konten soley auf einem Benutzernamen Basis, Denial-of-Service-Attacken agains bekannten Benutzernamen sperren würde
- Sperren auf IP/Benutzername Basis möglich sein (wobei Benutzername derjenige angegriffen ist) könnte besser funktionieren
mein Vorschlag: vollständige Sperre ist nicht wünschenswert (DOS), so eine bessere Alternative wäre: zählen Sie die Anmeldeversuche für einen bestimmten Benutzernamen von einer eindeutigen IP. Sie könnten dies mit einer einfachen Tabelle failed_logins: IP/username/failed_attempts
tun, wenn die Anmeldung fehlschlägt, wait(failed_attempts);
Sekunden. Führen Sie alle xx Minuten ein Cron-Skript aus, das failed_logins:failed_attempts
um eins verringert.
Entschuldigung, ich kann keine vorgefertigte Lösung bereitstellen, aber dies sollte trivial zu implementieren sein.
okay, okay.hier ist der Pseudo-Code:
<?php
$login_success = tryToLogIn($username, $password);
if (!$login_success) {
// some kind of unique hash
$ipusr = getUserIP() . $username;
DB:update('INSERT INTO failed_logins (ip_usr, failed_attempts) VALUES (:ipusr, 1) ON DUPLICATE KEY UPDATE failed_logins SET failed_attempts = failed_attempts+1 WHERE ip_usr=:ipusr', array((':ipusr' => $ipusr));
$failed_attempts = DB:selectCell('SELECT failed_attempts WHERE ip_usr=:ipusr', array(':ipusr' => $ipusr));
sleep($failed_attempts);
redirect('/login', array('errorMessage' => 'login-fail! ur doin it rong!'));
}
?>
Haftungsausschluss: dies nicht in bestimmten Regionen arbeiten. Das letzte, was ich gehört habe, war, dass es in Asien ein ganzes Land gibt (auch alle kennen Kung-Fu).
nette und einfache Lösung Ich stimme zu, aber es erfordert immer noch Datenbank-Interaktion. Was passiert, wenn ich einfach die 1-sekündige Verzögerung zwischen der fehlgeschlagenen Login-Erkennung und dem erneuten Rendern des Anmeldebildschirms hinzufüge? Dies würde sowohl Bots als auch Menschen zwingen, auf die Verzögerung warten zu müssen. Für einen Menschen ist es nicht viel, und nur wenige Menschen werden sich falsch einloggen, während es für einen Bot ziemlich lang ist. Was denken Sie? – Ferdy
das hilft nicht wirklich, weil ich N gleichzeitige Anfragen machen kann. Der 1-Sekunden-Block wird auf Anforderung ausgeführt, sodass die N gleichzeitigen Anforderungen nach etwas mehr als 1 Sekunde abgeschlossen werden (vorausgesetzt, der Server kann die Last verarbeiten). Im Prinzip könnte ich 10.000 Anfragen starten und sie nach einigen Sekunden beenden, weil sie nicht seriell sind. – stefs
auch, es gibt> 80.000 Sekunden pro Tag. 80.000 ist nicht viel für rohe Gewalt, aber es ist wahrscheinlich genug für einen Wörterbuchangriff. – stefs