Vous ne pouvez pas simplement empêcher les attaques par déni de service par le chaînage de la limitation vers le bas à une seule adresse IP ou le nom d'utilisateur. Enfer, vous ne pouvez même pas vraiment prévenir rapide-le-feu de tentatives de connexion à l'aide de cette méthode.
Pourquoi? Parce que l'attaque peut s'étendre sur plusieurs adresses ip et des comptes d'utilisateur pour le bien de contourner la limitation de tentatives.
J'ai vu posté ailleurs que, idéalement, vous devriez être suivi de tous les échecs de tentatives de connexion sur le site et de les associer à un timestamp, peut-être:
CREATE TABLE failed_logins (
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(16) NOT NULL,
ip_address INT(11) UNSIGNED NOT NULL,
attempted DATETIME NOT NULL,
INDEX `attempted_idx` (`attempted`)
) engine=InnoDB charset=UTF8;
Une note rapide sur l'adresse_ip champ: Vous pouvez stocker les données et récupérer les données, respectivement, avec INET_ATON() et INET_NTOA() qui correspondent à la conversion d'une adresse ip et d'un entier non signé.
# example of insertion
INSERT INTO failed_logins SET username = 'example', ip_address = INET_ATON('192.168.0.1'), attempted = CURRENT_TIMESTAMP;
# example of selection
SELECT id, username, INET_NTOA(ip_address) AS ip_address, attempted;
Décider sur un certain délai seuils sur la base de l' ensemble nombre de connexions échouées dans un laps de temps donné (15 minutes dans cet exemple). Vous devez vous baser sur des données statistiques tirées de votre failed_logins
tableau qu'il va changer au fil du temps basé sur le nombre d'utilisateurs et combien d'entre eux peut rappeler (et le type) de leur mot de passe.
> 10 failed attempts = 1 second
> 20 failed attempts = 2 seconds
> 30 failed attempts = reCaptcha
Requête de la table de chaque tentative de connexion a échoué à trouver le nombre de connexions échouées sur une période de temps, disons 15 minutes:
SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);
Si le nombre de tentatives au cours de la période de temps donnée est au-dessus de votre limite, soit de faire appliquer la limitation ou la force de l'utilisateur à utiliser un captcha (c'est à dire reCaptcha) jusqu'à ce que le nombre de tentatives infructueuses au cours de la période de temps donnée est inférieure à la valeur seuil.
// array of throttling
$throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');
// retrieve the latest failed login attempts
$sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$result = mysql_query($sql);
if (mysql_affected_rows($result) > 0) {
$row = mysql_fetch_assoc($result);
$latest_attempt = (int) date('U', strtotime($row['attempted']));
// get the number of failed attempts
$sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
$result = mysql_query($sql);
if (mysql_affected_rows($result) > 0) {
// get the returned row
$row = mysql_fetch_assoc($result);
$failed_attempts = (int) $row['failed'];
// assume the number of failed attempts was stored in $failed_attempts
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
if ($failed_attempts > $attempts) {
// we need to throttle based on delay
if (is_numeric($delay)) {
$remaining_delay = time() - $latest_attempt - $delay;
// output remaining delay
echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
} else {
// code to display recaptcha on login form goes here
}
break;
}
}
}
}
L'utilisation d'un reCaptcha à un certain seuil permettrait de s'assurer qu'une attaque à partir de plusieurs fronts serait arrêté et normal, les utilisateurs du site ne serait pas l'expérience d'un délai important pour légitime échecs de tentatives de connexion.