обновление: не используйте sleep () для ограничения скорости! это вообще не имеет смысла. у меня нет лучшего решения под рукой.
хорошим началом будет просто sleep(1);
после неудачной попытки входа в систему - легко реализовать, практически без ошибок.
1 секунда - это не так много для человека (особенно потому, что попытки входа в систему нередко случаются неудачно), но 1 секунда / попытка перебора ... sloooow! атака по словарю может быть другой проблемой, но она находится в том же домене.
если злоумышленник запускает слишком много соединений, чтобы обойти это, вы имеете дело с некой DOS-атакой. проблема решена (но теперь у вас есть другая проблема).
некоторые вещи, которые вы должны рассмотреть:
- если вы блокируете учетные записи только для отдельных IP-адресов, могут возникнуть проблемы с частными сетями.
- если вы блокируете учетные записи только на основе имени пользователя, возможны атаки типа «отказ в обслуживании» против известных имен пользователей
- блокировка на основе IP / имени пользователя (где имя пользователя атаковано) может работать лучше
мое предложение:
полная блокировка нежелательна (DOS), поэтому лучшей альтернативой будет: подсчет попыток входа для определенного имени пользователя с уникального IP-адреса. Вы можете сделать это с помощью простой таблицы failed_logins: IP/username/failed_attempts
, если не удается войти в систему, wait(failed_attempts);
секунд. Каждые xx минут запускайте скрипт cron, который уменьшается на failed_logins:failed_attempts
на единицу.
извините, я не могу предоставить готовое решение, но это должно быть тривиально для реализации.
хорошо, хорошо. вот псевдокод:
<?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!'));
}
?>
отказ от ответственности: это может не работать в определенных регионах. Последнее, что я услышал, было то, что в Азии есть целая страна NAT (также они все знают кунг-фу).