Я пытаюсь написать сценарий, чтобы предотвратить попытки входа в грубую силу на веб-сайте, который я создаю. Логика выглядит примерно так:
sleep(10)
, а затем сообщите пользователю о неудаче входа в систему. Объясняя это сотруднику, меня спросили, как это поможет, если хакер отправит, скажем, 1000 запросов за одну секунду. Будут ли первые 5 возвращаться сразу, а остальные оставшиеся 995 займут всего 10 секунд?
У меня есть подозрительное подозрение, что я не совсем понимаю, как работает HTTP – эта ситуация выше, чем возможно, или существует ли ограничение на количество одновременных запросов, которые сервер будет обрабатывать с одного клиента?
Будет ли лучшее решение иметь увеличение времени сна?
sleep($numRequestsInLast5Minutes - 5)
Таким образом, первые 5 будут быстрыми, а затем каждый последующий будет увеличивать сон.
Проблема заключается в балансе между доступностью пользователя и моделью злоумышленника.
If not password correct for a certain number of time: block the user send a reset link to the user
Пользователь : может быть заблокирован, и они не хотят перезагружать
Атакующий : заблокирован всех пользователей, пытаясь пройти аутентификацию для всех пользователей (особенно, если все логины общедоступны)
If not password correct: sleep(amount_of_time)
Вопрос в следующем: какова ценность «amount_of_time»?
Пользователь : может быть досадно ждать «amount_of_time» для каждой ошибки
Атакующий : продолжайте попытки, с более низким тестом / секундой
If not password correct: sleep(amount_of_time) amount_of_time = amount_of_time * 2
Пользователь : меньше раздражает за несколько ошибок пароля
Атакующий : заблокируйте пользователя для соединения, отправив много неправильного пароля
If not password correct for a certain number of time: submit a catchpa
Пользователь : нужно разрешить CAPTCHA (не слишком сложно)
Атакующий : необходимо разрешить CAPTCHA (должно быть сложно)
Хорошее решение (и используется многими сайтами), но будьте осторожны с нашей CAPTCHA. осуществление . Во всяком случае, есть трюк (см. Следующее решение).
If not password correct for a certain number of time: block the ip (eventually) send a reset link
Пользователь : Пользователь может быть заблокирован, потому что он не может правильно запомнить свой пароль.
Атакующий : пытается использовать один и тот же пароль с другим пользователем, поскольку блокировка основана на количестве логинов пользователя.
If several login attempts failed whatever is the user by an IP : print a CAPTCHA for this IP
Пользователь : пользователь не может быть заблокирован IP-адресом, но должен помнить пароль.
Атакующий : трудно иметь эффективную атаку грубой силы.
Является ли форма входа или ссылка на вход в систему, которая заблокирована? Блокирование формы входа бесполезно.
Устойчивость к грубой силе является ПЕРВОЙ проблемой сложности пароля, поэтому вам нужна строгая политика паролей (особенно в случае распределенной грубой силы).
Я не упоминаю факт, чтобы хэш ваши пароли с солью, вы уже делаете это правильно? Потому что, если легче получить доступ к базе паролей, чем грубая форсировка, злоумышленник выберет это решение ( «Цепочка только сильна, как ее слабая ссылка» ).
Я бы посоветовал, если пользователь пробовал безуспешно, скажем более пяти раз и пяти минут, вы сразу же возвращаете 503 Service Unavailable
для этого IP-адреса. Когда вход завершается с ошибкой, вы можете использовать memcache, чтобы получить текущие неудачные попытки для IP-адреса, а затем увеличить сумму и сохранить ее обратно в memcache с истечением 5 минут.
Вы не хотите sleep
в своем PHP-коде, так как это позволит одному пользователю создавать множество подключений к вашему веб-серверу и потенциально сбивать других пользователей.
Поскольку пользователь не вошел в систему, у вас нет файла cookie сеанса, и если пользователь пытается перевести его в учетную запись, они могут вообще не представлять файл cookie.
Я использовал что-то вроде этого …
Проверьте имя пользователя и пароль
1.1 Если нет совпадения, запишите последнее неудачное время входа для этой комбинации и количество неудачных входов.
1.2. Каждый сбой заставляет ждать, когда вы сможете войти в систему, например, failCount * 30 секунд, до максимума (например, 10 минут).
Я разработал это, но не выпустил его в дикую природу, поэтому любая обратная связь будет оценена по достоинству.
Я создал класс, который заботится о защите от грубой силы в PHP.
https://github.com/ejfrancis/BruteForceBlocker
он регистрирует все сбойные логины на всей территории страны в таблице db, и если количество неудачных логинов за последние 10 минут (или любой другой временной интервал, который вы выберете) превышает установленный предел, он обеспечивает временную задержку и / или требование капки перед тем, как войти в систему снова.
пример:
// создаем массив настроек дроссельной заслонки. (# 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 – необязательный параметр. если он не включен, будет использоваться массив настроек по умолчанию в BruteForceBlocker.php
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;
}
Я не уверен, что такое лучшая практика, но при работе с DoS-атаками лучшей стратегией является отключение трафика от вашего сервера. Настройка тайм-аутов на самом деле не поможет, поскольку вы все еще обрабатываете запрос и запускаете PHP.
Рассматривали ли вы настройку другого веб-сервера, на котором была запущена упрощенная версия вашей страницы входа? Когда пользователь пытается слишком много раз (например, тысячи раз), отправьте сообщение, чтобы настроить маршрутизатор и перенаправить этого пользователя на второй веб-сервер.
Это похоже на то, что веб-сайты попадают в эффект slashdot, многие из них просто перенаправляют трафик до тех пор, пока трафик не будет уменьшен.