1. Обзор
В этом руководстве мы опишем атаки перечислением в целом. В частности, мы рассмотрим атаки с перечислением имен пользователей на веб-приложения. И, самое главное, мы рассмотрим варианты их обработки с помощью Spring Security.
2. Объяснение атак перечислением
Технически перечисление означает полный и упорядоченный список всех элементов коллекции. Хотя это определение ограничено математикой, его суть делает его мощным инструментом взлома. Перечисление часто выявляет векторы атак, которые можно использовать для эксплуатации. В этом контексте его часто называют перечислением ресурсов.
Перечисление ресурсов, как следует из названия, — это способ собрать список ресурсов с любого хоста. Этими ресурсами может быть что угодно ценное, включая имена пользователей, сервисы или страницы. Эти ресурсы могут раскрыть потенциальные уязвимости в узле.
Теперь может быть несколько возможных способов, изученных или даже неисследованных, для использования этих уязвимостей.
3. Популярные атаки перечислением для веб-приложений
В веб-приложении одной из наиболее часто используемых атак с перечислением является атака с перечислением имени пользователя. Это в основном использует любую явную или неявную функцию веб-приложения для сбора действительных имен пользователей. Злоумышленник может использовать популярные варианты имени пользователя для атаки на веб-приложение.
Итак, какая функция в веб-приложении может определить, является ли имя пользователя действительным или нет? Честно говоря, он может быть самым разнообразным. Это может быть функция, разработанная, например, страница регистрации, сообщающая пользователю, что имя пользователя уже занято.
Или это может быть таким же неявным, как тот факт, что попытка входа в систему с действительным именем пользователя занимает совсем другое время по сравнению с попыткой входа в систему с недопустимым именем пользователя.
4. Настройка для эмуляции атаки перечислением имени пользователя
Мы будем использовать простое пользовательское веб-приложение, использующее Spring Boot и Spring Security, чтобы продемонстрировать эти векторы атак. Это веб-приложение будет иметь минимальный набор функций для поддержки демонстрации. Подробное обсуждение того, как настроить такое приложение, описано в предыдущем руководстве .
Общие функции веб-приложения часто раскрывают информацию, которая может использоваться для запуска атак с перечислением. Давайте пройдемся по ним.
4.1. Регистрация пользователя
Для регистрации пользователя требуется уникальное имя пользователя, а адрес электронной почты часто выбирается для простоты. Теперь, если мы выберем уже существующее электронное письмо, приложение должно сообщить нам об этом:
В сочетании с тем фактом, что список адресов электронной почты найти нетрудно, это может привести к атаке с перечислением имен пользователей, чтобы выудить действительные имена пользователей в приложении.
4.2. Логин пользователя
Точно так же, когда мы пытаемся войти в приложение, от нас требуется указать имя пользователя и пароль. Теперь, если предоставленное нами имя пользователя не существует, приложение может вернуть нам эту информацию:
Это, как и прежде, достаточно просто использовать для атаки перечислением имени пользователя.
4.3. Сброс пароля
Сброс пароля часто реализуется для отправки ссылки для сброса пароля на электронную почту пользователя. Теперь снова потребуется указать имя пользователя или адрес электронной почты:
Если это имя пользователя или адрес электронной почты не существует в приложении, приложение сообщит об этом, что приведет к аналогичной уязвимости, которую мы видели ранее.
5. Предотвращение атак с перечислением имен пользователей
Существует несколько способов предотвратить атаку с перечислением имени пользователя. Многих из них мы можем достичь с помощью простых настроек таких функций, как пользовательские сообщения в веб-приложении.
Более того, Spring Security со временем стала достаточно зрелой, чтобы поддерживать обработку многих из этих векторов атак. Существуют готовые функции и точки расширения для создания пользовательских мер безопасности. Мы рассмотрим некоторые из этих методов.
Давайте рассмотрим популярные варианты, доступные для предотвращения таких атак. Обратите внимание, что не все эти решения подходят или даже возможны в каждой части веб-приложения. Мы обсудим это более подробно по ходу дела.
5.1. Настройка сообщений
Во-первых, мы должны исключить все возможности непреднамеренной выдачи большего количества информации, чем требуется. Это было бы сложно при регистрации, но довольно просто на страницах входа и сброса пароля.
Например, мы можем легко сделать сообщение для страницы входа абстрактным:
Мы можем внести аналогичные изменения в сообщение для страницы сброса пароля.
5.2. Включая CAPTCHA
Хотя настройка сообщений работает хорошо на некоторых страницах, есть такие страницы, как регистрация, где это сделать сложно. В таких случаях мы можем использовать другой инструмент под названием CAPTCHA.
Теперь, в этот момент, стоит отметить, что любая атака перечислением, скорее всего, является роботизированной из-за огромного количества возможностей для прохождения. Следовательно, обнаружение присутствия человека или робота может помочь нам предотвратить атаку . CAPTCHA служит популярным способом добиться этого.
Существует несколько возможных способов реализации или интеграции сервисов CAPTCHA в веб-приложение. Одним из таких сервисов является reCAPTCHA от Google, который легко интегрируется на странице регистрации .
5.3. Ограничение скорости
Хотя CAPTCHA хорошо служит этой цели, она увеличивает задержку и, что более важно, создает неудобства для законных пользователей. Это более актуально для часто используемых страниц, таких как логин.
Одним из методов, который может помочь предотвратить роботизированные атаки на часто используемые страницы, такие как вход в систему, является ограничение скорости . Ограничение скорости относится к предотвращению последовательных попыток доступа к ресурсу после определенного порога.
Например, мы можем заблокировать запросы с определенного IP на сутки после трех неудачных попыток входа в систему:
Spring Security делает это особенно удобным.
Начнем с определения слушателей для AuthenticationFailureBadCredentialsEvent и AuthenticationSuccessEvent.
Эти прослушиватели вызывают службу, которая записывает количество неудачных попыток с определенного IP-адреса. После превышения установленного порога последующие запросы блокируются в UserDetailsService
.
Подробное обсуждение этого подхода доступно в другом туториале .
5.4. Географические ограничения
Кроме того, мы можем фиксировать местоположение пользователя по стране во время регистрации. Мы можем использовать это для проверки попытки входа в систему из другого места. Если мы обнаружим необычное местоположение, можно предпринять соответствующие действия:
- Выборочное включение Captcha
- Принудительная пошаговая аутентификация (как часть многофакторной аутентификации)
- Попросите пользователя надежно подтвердить местоположение
- Временно заблокировать пользователя при последовательных запросах
Опять же, Spring Security через свои точки расширения позволяет подключить настраиваемую службу проверки местоположения в AuthenticationProvider
. Конкретный вариант этого был подробно описан в предыдущем уроке .
5.5. Многофакторная аутентификация
Наконец, мы должны отметить, что аутентификация на основе пароля часто является первым и, в большинстве случаев, единственным необходимым шагом. Но приложения нередко используют механизмы многофакторной аутентификации для повышения безопасности . Это особенно актуально для чувствительных приложений, таких как онлайн-банкинг.
Существует много возможных факторов, когда речь идет о многофакторной аутентификации:
- Фактор знаний: это относится к тому, что пользователь знает, например, PIN-код.
- Фактор владения: относится к тому, чем владеет пользователь, например токеном или смартфоном.
- Фактор неотъемлемости: относится к тому, что изначально есть у пользователя, например отпечатки пальцев.
Spring Security здесь также весьма удобен, так как позволяет нам подключить собственный AuthenticationProvider.
Приложение Google Authenticator является популярным выбором для реализации дополнительного фактора владения. Это позволяет пользователям генерировать эфемерный токен в приложении на своем смартфоне и использовать его для аутентификации в любом приложении. Очевидно, что это требует предварительной настройки пользователя в приложении, либо при регистрации, либо позже.
Что еще более важно, такое решение, как многофакторная аутентификация, подходит только в том случае, если оно необходимо приложению . Следовательно, мы не должны использовать его в первую очередь для предотвращения атак с перечислением.
5.6. Задержки времени обработки
При обработке запроса, такого как логин, проверка существования имени пользователя часто является самым первым, что мы делаем. Если имя пользователя не существует, запрос немедленно возвращается с ошибкой. Напротив, запрос с действительным именем пользователя потребует много дополнительных шагов, таких как сопоставление пароля и проверка роли. Естественно, время ответа в обоих этих случаях может быть разным.
Теперь, несмотря на то, что мы абстрагируем сообщение об ошибке, чтобы скрыть факт того, действительно ли имя пользователя или нет, значительная разница во времени обработки может насторожить злоумышленника.
Возможным решением этой проблемы может быть добавление принудительной задержки, чтобы исключить разницу во времени обработки. Однако, поскольку это не проблема, которая может возникнуть с уверенностью, мы должны использовать это решение только в случае необходимости.
6. Подведение итогов
Хотя мы рассмотрели множество приемов, которые можно использовать, когда дело доходит до атак с перечислением имен пользователей, естественно спросить, когда что использовать? Очевидно, что на этот вопрос нет однозначного ответа, так как он во многом зависит от типа приложения и его требований.
Несколько вещей, таких как сообщения пользователю, должны передавать как можно меньше информации. Кроме того, целесообразно ограничить последовательные неудачные попытки доступа к такому ресурсу, как вход в систему.
Однако мы должны использовать любые дополнительные меры только в том случае, если требования сочтут их необходимыми. Мы также должны рационально сопоставить их с сдерживающим фактором для удобства использования.
Более того, важно понимать, что мы можем применять любую комбинацию этих мер для различных ресурсов, чтобы выборочно защитить их.
7. Заключение
В этом руководстве мы обсудили атаки с перечислением — в частности, атаки с перечислением имени пользователя. Мы видели это через призму простого приложения Spring Boot с Spring Security.
Мы рассмотрели несколько способов постепенного решения проблем, связанных с атаками с перечислением имен пользователей.
Наконец, мы обсудили уместность этих мер в безопасности приложений.
Как всегда, код примеров доступен на GitHub .