Найдите ошибку в защите входа: лимит неудачных попыток считается отдельно для каждого IP-адреса. Какой основной риск нужно подтвердить?
Основной риск — обход ограничения распределением попыток между множеством IP-адресов. В результате злоумышленник может проводить масштабированный подбор паролей, хотя каждый отдельный адрес формально не превышает установленный лимит.
Ограничение частоты запросов появилось как практическая защита от автоматизированного перебора паролей и чрезмерной нагрузки на сервис. Привязка лимита к IP-адресу была простой для реализации, потому что IP виден серверу на каждом сетевом запросе.
Однако современные атаки выполняются через ботнеты, прокси и сети NAT. Поэтому один IP не всегда соответствует одному пользователю, а один злоумышленник может менять адрес после небольшого числа попыток.
Если счётчик ошибок ведётся только по IP, атакующий может распределить попытки по тысячам адресов. Это снижает вероятность срабатывания лимита для каждой отдельной записи и позволяет проверять большое количество паролей или учётных записей.
Дополнительная проблема возникает за общим прокси: множество легитимных пользователей могут иметь один внешний IP. Жёсткий лимит только по этому признаку способен заблокировать добросовестных пользователей и при этом не остановить распределённую атаку.
Тестировщик должен сначала установить базовое поведение: зафиксировать число неудачных входов с одного адреса, момент срабатывания ограничения, длительность блокировки и реакцию сервиса. Затем те же попытки нужно распределить между несколькими адресами, сохраняя одну целевую учётную запись или один набор проверяемых учётных записей.
Если суммарное число попыток значительно превышает ожидаемый предел, а сервис не применяет дополнительное ограничение, риск подтверждён. Важно проверять не только HTTP-ответ, но и фактический результат: возможность продолжать подбор, отсутствие задержки, отсутствие временной блокировки и различие поведения для существующих и несуществующих учётных записей.
Надёжнее применять несколько независимых измерений: лимит на IP или подсеть, на учётную запись, на идентификатор клиента и на общую нагрузку от источника. Эти ограничения должны дополнять друг друга, а не заменять проверку пароля. Для чувствительных операций полезны возрастающие задержки, многофакторная аутентификация и обнаружение аномалий.
Доверять переданному клиентом адресу можно только при корректно настроенной цепочке доверенных прокси. Иначе заголовок с адресом клиента можно подменить, превратив ограничение по IP в полностью обходную защиту. При этом нельзя бездумно блокировать пользователя после нескольких ошибок: такая схема создаёт возможность намеренно лишать доступа владельцев чужих учётных записей.
API входа разрешал десять ошибок с одного IP за минуту. При последовательной проверке с одного адреса лимит срабатывал, но при распределении запросов через пул адресов можно было продолжать подбор без заметного замедления.
Рассматривались три варианта. Полный отказ от IP-ограничения устранил бы проблемы с NAT, но оставил бы сервис без важного слоя защиты. Жёсткая блокировка учётной записи после нескольких ошибок лучше останавливала подбор, но позволяла бы злоумышленнику блокировать чужие аккаунты. Ограничение только по заголовку клиентского IP было проще, но небезопасно при недоверенной прокси-цепочке.
Выбрали комбинированный подход: отдельные мягкие лимиты по учётной записи и источнику, возрастающую задержку для повторных ошибок, контроль общего объёма попыток и многофакторную аутентификацию для рискованных входов. Тест повторили с одним IP, несколькими IP и общим прокси; подбор замедлялся, а легитимные пользователи не блокировались постоянным отказом.
Достаточно ли проверять только ограничение по IP? Нет. IP — лишь один из признаков источника и часто описывает не пользователя, а прокси, NAT или узел ботнета. Нужно оценивать совокупность ограничений и проверять, что распределение запросов не позволяет неограниченно увеличивать скорость перебора.
Можно ли безопасно ограничивать попытки по имени учётной записи? Да, но предпочтительно использовать задержки или мягкое временное ограничение, а не постоянную блокировку. Иначе любой внешний злоумышленник сможет намеренно отправить несколько неверных паролей для чужого имени и вызвать отказ в обслуживании учётной записи.
Почему равные ответы для существующего и несуществующего имени важны при проверке лимита? Различия во времени, тексте ответа или применении лимита могут раскрывать существующие учётные записи. Поэтому тестировщик должен убедиться, что механизм против перебора не создаёт дополнительный канал перечисления пользователей и одинаково обрабатывает оба случая.