paint-brush
Защита вашего веб-приложения: руководство по ограничению скорости и предотвращению атак методом переборак@shad0wpuppet
27,209 чтения
27,209 чтения

Защита вашего веб-приложения: руководство по ограничению скорости и предотвращению атак методом перебора

Слишком долго; Читать

Реализация надежных мер по ограничению скорости необходима для веб-приложений, чтобы предотвратить атаки грубой силы и потенциальную перегрузку сервисов. Методы ограничения скорости и идеи тестирования и обхода ограничений скорости. В статье рассматривается подход к автоматизации, манипуляции с заголовками, варианты конечных точек и стратегии, связанные с входом в систему. Также изучается возможность использования Cloudflare для восстановления исходных IP-адресов посетителей, но с осторожностью перед внедрением тщательно протестируйте и оцените потенциальное влияние на приложение.
featured image - Защита вашего веб-приложения: руководство по ограничению скорости и предотвращению атак методом перебора
Konstantin Sakhchinskiy HackerNoon profile picture
0-item


Если ваше приложение включает в себя фундаментальные функции, такие как вход в систему, регистрацию, сброс/восстановление пароля, повторную отправку ссылок для подтверждения и другие специфические функции, требующие запросов к серверу, крайне важно реализовать механизмы против атак методом перебора и создания значительной нагрузки на ваш сервис. Без таких механизмов ваше приложение может быть уязвимо для различных угроз, включая отправку пользователям чрезмерного количества электронных писем/OTP, что потенциально может привести к финансовому и репутационному ущербу.


Многим веб-приложениям не хватает адекватных мер по ограничению скорости, поскольку они полагаются исключительно на ограничения, налагаемые их бизнес-логикой, например ограничение количества запросов на основе модели оплаты. Однако некоторые приложения включают ограничения скорости, особенно для таких операций, как попытки входа в систему, регистрация и другие важные функции. Эти реализации часто зависят от заголовка X-Forwarded-For для отслеживания IP-адресов.


Чтобы проиллюстрировать простой пример, я придумал этот фрагмент кода на Flask.


 from flask import Flask, request, jsonify from flask_limiter import Limiter from flask_limiter.util import get_remote_address app = Flask(__name__) limiter = Limiter(    app,    key_func=get_remote_address,    storage_uri="memory://",) def get_ipaddr():    # Retrieve the client's IP address from the request    # X-Forwarded-For header is used to handle requests behind a proxy    ip_address = request.headers.get('X-Forwarded-For', request.remote_addr)    return ip_address # Rate limit to 5 requests per minute per IP @limiter.limit("5 per minute") @app.route('/') def index(): ip_address = get_ipaddr() return ip_address

В следующих разделах я объясню различные подходы к тестированию и попыткам обойти ограничения скорости в вашем приложении.


Для эффективного тестирования вашего приложения на наличие уязвимостей такого типа автоматизация является мощным инструментом. Вы можете добиться этого, используя сценарии, например, на Python (как я часто делаю), или используя такие инструменты, как Burp Suite (кстати, отличный инструмент для тестировщиков и специалистов по кибербезопасности). Кроме того, такие инструменты, как Postman, можно относительно легко использовать для автоматизации проверок.

Ограничение скорости тестирования

Изменение значения IP в заголовке X-Forwarded-For

 X-Originating-IP: 127.0.0.1

Используйте разные значения IP в каждом отправляемом запросе.


Используйте двойной заголовок X-Forwared-For.

 X-Forwarded-For: X-Forwarded-For: 127.0.0.1

Попробуйте то же самое с разными заголовками.

 X-Originating-IP: 127.0.0.1 X-Remote-IP: 127.0.0.1 X-Remote-Addr: 127.0.0.1 X-Client-IP: 127.0.0.1 X-Host: 127.0.0.1 X-Forwared-Host: 127.0.0.1

Изменить другие заголовки

Попробуйте изменить пользовательский агент, тип контента, язык принятия и т. д. или файлы cookie — все, что может использоваться в качестве идентификатора пользователя.


Если существует ограничение скорости в 3 попытки на один IP-адрес, каждые три попытки меняйте значение IP-адреса заголовка (или других заголовков или параметров в ваших запросах).

Добавить пустые символы в параметры

Попробуйте добавить к отправленным вами параметрам

 %00, %0d%0a, %0d, %0a, %09, %0C, %20

Например

 param1=value1%%0d%0a param2=value2%00

Например, если вы запрашиваете OTP для подтверждения электронной почты и у вас есть только 3 попытки, используйте 3 попытки для

 [email protected] [email protected]%00 [email protected]%0d%0a And so on

Используйте похожие конечные точки

Если вы тестируете, например, конечную точку /API/v1/signup, попробуйте выполнить перебор к /Signup, /SignUp, /sign-up. Попробуйте добавить пустые символы (из приведенных выше) к исходным конечным точкам.

Добавление дополнительных параметров в запрошенную конечную точку API

Если ограничение установлено на запросы конечной точки /api/v1/resetpassword, попробуйте перебрать его, добавив некоторые параметры запроса. Как только предел скорости будет достигнут, попробуйте, например, /api/v1/resetpassword?param1=value1

Логины имеют значение

Возможно, приложение имеет ошибочную логику: если вы входите в свою учетную запись перед каждой попыткой/серией попыток, ограничение скорости для вашего IP-адреса сбрасывается, и вы можете продолжить атаку методом подбора пароля. Если вы тестируете функцию входа в систему, вы можете сделать это в Burp Suit с атакой Pitchfork в настройках (или вы можете написать для этого свой собственный скрипт) для каждой попытки/серии попыток.


Вот мой пример того, как я автоматизировал простую проверку заголовка X-Forwarded-For только для получения POW:


 from random import randint import requests import json url = "https://yourapp.net/api/v1/regconfirm-resend" data = {   "email": "[email protected]" } N = 100 def generate_random_ip():   return '.'.join(       str(randint(0, 255)) for _ in range(4)   ) for _ in range(N):   headers = {       "Host": "yourapp.net",       "Content-Type": "application/json",       "X-Forwarded-For": generate_random_ip()   }   response = requests.post(url, headers=headers, data=json.dumps(data))   print(headers)   print(f"Status Code: {response.status_code}, Response: {response.text}")

Восстановление исходных IP-адресов посетителей

Возможным решением может быть использование Cloudflare и его механизмов. Подробное объяснение можно найти здесь restoring-original-visitor-ips . Я предоставлю лишь краткий обзор его защитных механизмов.


Если вы используете приложения, которые зависят от входящего IP-адреса исходного посетителя, по умолчанию регистрируется IP-адрес Cloudflare. Исходный IP-адрес посетителя отображается в добавленном HTTP-заголовке под названием CF-Connecting-IP. Следуя инструкциям нашего веб-сервера, вы можете зарегистрировать исходный IP-адрес посетителя на исходном сервере. Если этот HTTP-заголовок недоступен, когда запросы достигают исходного сервера, проверьте правила преобразования и конфигурацию управляемых преобразований.


Если для псевдо-IPv4 установлено значение «Перезаписать заголовки», Cloudflare перезаписывает существующие заголовки Cf-Connecting-IP и X-Forwarded-For псевдоIPv4-адресом, сохраняя при этом реальный адрес IPv6 в заголовке CF-Connecting-IPv6.


ПРИМЕЧАНИЕ. Помните: при реализации такого защитного механизма необходимо провести тщательное тестирование. Этот подход впоследствии может быть применен ко всему кластеру и может отрицательно повлиять на определенные функции и микросервисы там, где в нем нет необходимости. Короче говоря, при устранении нарушений безопасности будьте осторожны, поскольку это потенциально может повлиять на все приложение. Проанализируйте, какая часть вашей системы может быть затронута негативно, и протестируйте все перед отправкой изменений в рабочую среду.


Также опубликовано здесь .