Si su aplicación incluye características fundamentales como inicio de sesión, registro, restablecimiento/recuperación de contraseña, enlaces de confirmación de reenvío y otras funcionalidades específicas que requieren solicitudes del servidor, es crucial implementar mecanismos contra ataques de fuerza bruta y la generación de una carga sustancial en su servicio. Sin dichos mecanismos, su aplicación puede ser vulnerable a diversas amenazas, incluido el envío de una cantidad excesiva de correos electrónicos/OTP a los usuarios, lo que podría provocar daños financieros y de reputación.
Muchas aplicaciones web carecen de medidas adecuadas de limitación de tarifas y se basan únicamente en las limitaciones impuestas por su lógica empresarial, como restringir el número de solicitudes en función de un modelo de pago. Sin embargo, algunas aplicaciones incorporan límites de velocidad, particularmente para operaciones como intentos de inicio de sesión, registro y otras funcionalidades críticas. Estas implementaciones a menudo dependen del encabezado X-Forwarded-For para el seguimiento de direcciones IP.
Para ilustrar un ejemplo simple, se me ocurrió este fragmento de código en 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
En las siguientes secciones, explicaré varios enfoques para probar e intentar eludir los límites de velocidad en su aplicación.
Para probar de manera eficiente su aplicación para detectar este tipo de vulnerabilidad, la automatización es una herramienta poderosa. Puede lograr esto empleando scripts, como los de Python (como hago a menudo), o usando herramientas como Burp Suite (por cierto, una gran herramienta para evaluadores y profesionales de la ciberseguridad). Además, se pueden utilizar herramientas como Postman para automatizar comprobaciones con relativa facilidad.
X-Originating-IP: 127.0.0.1
Utilice diferentes valores de IP en cada solicitud que envíe.
Utilice el encabezado doble X-Forwared-For.
X-Forwarded-For: X-Forwarded-For: 127.0.0.1
Pruebe lo mismo con diferentes encabezados.
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
Intente cambiar el agente de usuario, el tipo de contenido, el idioma de aceptación, etc., o las cookies, cualquier cosa que pueda usarse como identificador de usuario.
Si hay un límite de velocidad de 3 intentos por IP, cada tres intentos, cambie el valor de IP del encabezado (u otros encabezados o parámetros en sus solicitudes).
Intente agregar a los parámetros que envía
%00, %0d%0a, %0d, %0a, %09, %0C, %20
Por ejemplo
param1=value1%%0d%0a param2=value2%00
Por ejemplo, si solicita OTP para la verificación de correo electrónico y solo tiene 3 intentos, use los 3 intentos para
[email protected] [email protected]%00 [email protected]%0d%0a And so on
Si está probando, por ejemplo, el punto final /API/v1/signup, intente realizar fuerza bruta en /Signup, /SignUp, /sign-up. Intente agregar caracteres en blanco (de los anteriores) a los puntos finales originales.
Si el límite está en las solicitudes del punto final /api/v1/resetpassword, intente aplicar fuerza bruta agregando algunos parámetros de consulta; una vez que se alcance el límite de velocidad, intente, por ejemplo, /api/v1/resetpassword?param1=value1
Podría darse el caso de que una aplicación tenga una lógica defectuosa: si inicia sesión en su cuenta antes de cada intento/serie de intentos, el límite de velocidad se restablece para su IP y puede continuar con el ataque de fuerza bruta de su contraseña. Si está probando una función de inicio de sesión, puede hacerlo en Burp Suit con un ataque Pitchfork en la configuración (o puede escribir su propio script para esto) para cada intento/serie de intentos.
Este es mi ejemplo de cómo automaticé una verificación simple del encabezado X-Forwarded-For solo para obtener un 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}")
Una posible solución podría ser el uso de Cloudflare y sus mecanismos. Puede encontrar una explicación detallada aquí restaurando-original-visitante-ips . Proporcionaré sólo una breve descripción de sus mecanismos de defensa.
Si utiliza aplicaciones que dependen de la dirección IP entrante del visitante original, se registra una dirección IP de Cloudflare de forma predeterminada. La dirección IP del visitante original aparece en un encabezado HTTP adjunto llamado CF-Connecting-IP. Siguiendo las instrucciones de nuestro servidor web, puede registrar la dirección IP del visitante original en su servidor de origen. Si este encabezado HTTP no está disponible cuando las solicitudes llegan a su servidor de origen, verifique su configuración de Reglas de transformación y Transformaciones administradas.
Si Pseudo IPv4 está configurado para Sobrescribir encabezados, Cloudflare sobrescribe los encabezados Cf-Connecting-IP y X-Forwarded-For existentes con una pseudo dirección IPv4 y al mismo tiempo conserva la dirección IPv6 real en el encabezado CF-Connecting-IPv6.
NOTA: Recuerde, al implementar dicho mecanismo de defensa, realice pruebas exhaustivas. Este enfoque podría aplicarse posteriormente a todo el clúster y podría afectar negativamente a determinadas funciones y microservicios cuando no sea necesario. En pocas palabras, al solucionar una brecha de seguridad, tenga cuidado, ya que podría afectar a toda la aplicación. Analice qué parte de su sistema podría verse afectada negativamente y pruebe todo antes de enviar cambios al entorno de producción.
También publicado aquí .