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

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

23 января 2024 г.

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

Многие веб-приложения не имеют адекватных мер по ограничению скорости и полагаются исключительно на ограничения, налагаемые их бизнес-логикой, например ограничение количества запросов на основе модели оплаты. Однако некоторые приложения включают ограничения скорости, особенно для таких операций, как попытки входа в систему, регистрация и другие важные функции. Эти реализации часто зависят от заголовка 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 попытки для

example@email.com
example@email.com%00
example@email.com%0d%0a
And so on

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

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

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

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

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

Возможно, логика приложения некорректна: если вы входите в свою учетную запись перед каждой попыткой/серией попыток, ограничение скорости для вашего 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": "yourtest@mail.com"
}

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.

>

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


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


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE