Дросселирование попыток входа в систему
(Это в основном язык-агностический вопрос, хотя в моем случае я использую ASP.NET 3.5)
Я использую стандартный ASP.NET элемент управления входами и хотел бы реализовать следующую неудачную логику дросселирования логина.
- Обработайте событие
OnLoginError
и сохраните в Session, количество неудачных попыток входа в систему.
- Когда этот счет попадает в [некоторое настраиваемое значение], блокирует дальнейшие попытки входа из исходного IP-адреса или для этого пользователя/этих пользователей в течение 1 часа
Это звучит как разумный подход? Не хватает ли я очевидных средств, с помощью которых такие проверки можно было бы обойти?
Примечание: сеанс ASP.NET связан с пользовательским браузером с помощью файла cookie
Изменить
Это для сайта администрирования, который будет использоваться только из Великобритании и Индии.
Ответы
Ответ 1
Джефф Этвуд упомянул другой подход: вместо того, чтобы блокировать учетную запись после нескольких попыток, увеличьте время до тех пор, пока не будет разрешена другая попытка входа в систему:
1st failed login no delay
2nd failed login 2 sec delay
3rd failed login 4 sec delay
4th failed login 8 sec delay
5th failed login 16 sec delay
Это снизит риск того, что эта мера защиты может быть использована для атак типа "отказ в обслуживании".
См. http://www.codinghorror.com/blog/archives/001206.html
Ответ 2
Последнее, что вы хотите сделать, - это сохранить все неудачные попытки входа в базу данных, которые будут работать достаточно хорошо, но также делает чрезвычайно тривиальным для DDOS-атак, чтобы снизить ваш сервер базы данных.
Вероятно, вы используете некоторый тип кеша на стороне сервера на своем веб-сервере, memcached или аналогичном. Это идеальные системы для отслеживания неудачных попыток с помощью IP-адреса и/или имени пользователя. Если превышен определенный порог неудачных попыток входа в систему, вы можете решить деактивировать учетную запись в базе данных, но вы сохраните кучу чтений и записи в ваше постоянное хранилище для неудачных счетчиков входа, которые вам не нужны сохраняются.
Если вы пытаетесь остановить людей от принудительной аутентификации, система дросселирования, такая как Gumbo, предположительно работает лучше всего. Это сделает атаки грубой силы неинтересными для злоумышленника, одновременно минимизируя воздействие для законных пользователей при нормальных обстоятельствах или даже во время атаки. Я бы предложил просто подсчитать неудачные попытки IP в memcached или подобном, и если вы когда-нибудь станете объектом чрезвычайно распространенной атаки грубой силы, вы всегда можете выбрать, чтобы также отслеживать попытки на одно имя пользователя, предполагая, что злоумышленники на самом деле часто пытается использовать одно и то же имя пользователя. До тех пор, пока попытка не будет чрезвычайно распространена, поскольку все еще происходит от счетного количества IP-адресов, исходный по-IP-код должен держать атакующих довольно адекватно.
Ключом к предотвращению проблем с посетителями из стран с ограниченным количеством IP-адресов является то, что вы не слишком строгие пороговые значения; если вы не получите несколько попыток за пару секунд, вам, вероятно, нечего беспокоиться о re. сценарий грубой силы. Если вас больше беспокоят люди, пытающиеся разгадать другие пароли пользователей вручную, вы можете установить более широкие границы для последующих неудачных попыток входа в систему по имени пользователя.
Еще одно предложение, которое не отвечает на ваш вопрос, но несколько связано с ним, заключается в обеспечении определенного уровня безопасности паролей для ваших конечных пользователей. Я бы не пошел за борт с требованием смешанного флага, хотя бы х символов, не-словаря и т.д. И т.д., Потому что вы не хотите многого жуть людей, когда они еще не подписались, но просто останавливая людей от использования своего имени пользователя, поскольку их пароль должен пройти очень долгий путь, чтобы защитить ваш сервис и пользователей от самых простых - догадывайтесь, почему они называют их грубой силой;) - атак.
Ответ 3
Принятый ответ, который вставляет возрастающие задержки в последовательные попытки входа в систему, может очень плохо работать в ASP.NET в зависимости от того, как он реализован. ASP.NET использует пул потоков для обслуживания запросов. Когда этот пул потоков исчерпан, входящие запросы будут поставлены в очередь до тех пор, пока поток не станет доступен.
Если вы вставляете задержку с помощью Thread.Sleep(n), вы будете связывать поток пула потоков ASP.NET на время задержки. Этот поток больше не будет доступен для выполнения других запросов. В этом случае простая атака типа DOS будет заключаться в том, чтобы продолжать отправлять вашу регистрационную форму. В конце концов каждый поток, доступный для выполнения запросов, будет спать (и для увеличения периода времени).
Единственный способ, с помощью которого я могу правильно реализовать этот механизм задержки, - использовать асинхронный обработчик HTTP. См. Пошаговое руководство. Создание асинхронного обработчика HTTP. Для реализации, вероятно, потребуется:
- Попытка аутентификации во время BeginProcessRequest и определение задержки при сбое
- Возвращает IAsyncResult, выставляющий WaitHandle, который будет запущен после задержки
- Убедитесь, что WaitHandle был запущен (или заблокирован до тех пор, пока он не был) в EndProcessRequest
Ответ 4
Это может повлиять на ваших настоящих пользователей. Напр. в таких странах, как Сингапур, ограниченное количество интернет-провайдеров и меньший набор IP-адресов, доступных для домашних пользователей.
В качестве альтернативы вы могли бы добавить капчу после неудачных попыток x прервать script kiddies.
Ответ 5
Я думаю, вам нужно будет держать счет за пределами сеанса - иначе тривиальная атака - очистить файлы cookie перед каждой попыткой входа.
В противном случае подсчет и блокировка являются разумными - хотя более простым решением может быть двойной перерыв между каждым неудачей входа. то есть через 2 секунды после первой попытки входа в систему, через 4 секунды после следующего, 8 и т.д.
Вы реализуете тайм-аут, отказываясь от входа в период таймаута - даже если пользователь дает правильный пароль - просто ответьте человеческим читаемым текстом, указав, что учетная запись заблокирована.
Также отслеживайте для одного и того же ip/другого пользователя и того же пользователя/другого ip.