Если ваше приложение включает в себя фундаментальные функции, такие как вход в систему, регистрацию, сброс/восстановление пароля, повторную отправку ссылок для подтверждения и другие специфические функции, требующие запросов к серверу, крайне важно реализовать механизмы против атак методом перебора и создания значительной нагрузки на ваш сервис. Без таких механизмов ваше приложение может быть уязвимо для различных угроз, включая отправку пользователям чрезмерного количества электронных писем/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, можно относительно легко использовать для автоматизации проверок.
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/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}")
Возможным решением может быть использование 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.
ПРИМЕЧАНИЕ. Помните: при реализации такого защитного механизма необходимо провести тщательное тестирование. Этот подход впоследствии может быть применен ко всему кластеру и может отрицательно повлиять на определенные функции и микросервисы там, где в нем нет необходимости. Короче говоря, при устранении нарушений безопасности будьте осторожны, поскольку это потенциально может повлиять на все приложение. Проанализируйте, какая часть вашей системы может быть затронута негативно, и протестируйте все перед отправкой изменений в рабочую среду.
Также опубликовано здесь .