paint-brush
Defendendo seu aplicativo da Web: um guia para limitação de taxa e prevenção de ataques de força brutapor@shad0wpuppet
27,215 leituras
27,215 leituras

Defendendo seu aplicativo da Web: um guia para limitação de taxa e prevenção de ataques de força bruta

por Konstantin Sakhchinskiy4m2024/01/22
Read on Terminal Reader
Read this story w/o Javascript

Muito longo; Para ler

A implementação de medidas robustas de limitação de taxa é essencial para que os aplicativos da Web evitem ataques de força bruta e possível sobrecarga de serviço. Técnicas de limitação de taxa e insights sobre como testar e contornar limites de taxa. O artigo aborda a abordagem de automação, manipulações de cabeçalho, variações de endpoint e estratégias relacionadas a login. O uso da Cloudflare para restaurar IPs de visitantes originais também é explorado, com cautela para testar e avaliar minuciosamente os impactos potenciais no aplicativo antes da implementação.
featured image - Defendendo seu aplicativo da Web: um guia para limitação de taxa e prevenção de ataques de força bruta
Konstantin Sakhchinskiy HackerNoon profile picture
0-item


Se sua aplicação inclui recursos fundamentais como login, registro, redefinição/recuperação de senha, reenvio de links de confirmação e outras funcionalidades específicas que exigem solicitações do servidor, é crucial implementar mecanismos contra ataques de força bruta e a geração de uma carga substancial em seu serviço. Sem esses mecanismos, seu aplicativo pode ficar vulnerável a diversas ameaças, incluindo o envio de um número excessivo de e-mails/OTPs aos usuários, o que pode levar a danos financeiros e à reputação.


Muitas aplicações web carecem de medidas adequadas de limitação de taxas, baseando-se apenas nas limitações impostas pela sua lógica de negócio, tais como a restrição do número de pedidos com base num modelo de pagamento. Alguns aplicativos, no entanto, incorporam limites de taxa, especialmente para operações como tentativas de login, registro e outras funcionalidades críticas. Essas implementações geralmente dependem do cabeçalho X-Forwarded-For para rastreamento de endereços IP.


Para ilustrar um exemplo simples, criei este trecho de código no 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

Nas seções a seguir, explicarei várias abordagens para testar e tentar contornar os limites de taxa em seu aplicativo.


Para testar seu aplicativo com eficiência quanto a esse tipo de vulnerabilidade, a automação é uma ferramenta poderosa. Você pode conseguir isso empregando scripts, como aqueles em Python (como costumo fazer), ou usando ferramentas como Burp Suite (aliás, uma ótima ferramenta para testadores e profissionais de segurança cibernética). Além disso, ferramentas como o Postman podem ser usadas para automatizar verificações com relativa facilidade.

Limite de taxa de teste

Alterando o valor IP no cabeçalho X-Forwarded-For

 X-Originating-IP: 127.0.0.1

Use valores de IP diferentes em cada solicitação enviada.


Use o cabeçalho duplo X-Forwared-For.

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

Tente o mesmo com cabeçalhos diferentes.

 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

Alterar outros cabeçalhos

Tente alterar o agente do usuário, tipo de conteúdo, idioma de aceitação, etc., ou cookies, qualquer coisa que possa ser usada como identificador de usuário.


Se houver um limite de taxa de 3 tentativas por IP, a cada três tentativas, altere o valor IP do cabeçalho (ou outros cabeçalhos ou parâmetros em suas solicitações).

Adicione caracteres em branco nos parâmetros

Tente adicionar aos parâmetros que você envia

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

Por exemplo

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

Por exemplo, se você estiver solicitando OTP para verificação de e-mail e tiver apenas 3 tentativas, use as 3 tentativas para

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

Use endpoints semelhantes

Se você estiver testando, por exemplo, o endpoint /API/v1/signup, tente executar força bruta em /Signup, /SignUp, /sign-up. Tente adicionar caracteres em branco (acima) aos pontos de extremidade originais.

Adicionando parâmetros extras ao endpoint de API solicitado

Se o limite estiver nas solicitações do endpoint /api/v1/resetpassword, tente forçá-lo adicionando alguns parâmetros de consulta - quando o limite de taxa for atingido, tente, por exemplo, /api/v1/resetpassword?param1=value1

Logins são importantes

Pode ser que um aplicativo tenha uma lógica falha - se você fizer login em sua conta antes de cada tentativa/série de tentativas, o limite de taxa será redefinido para seu IP e você poderá continuar seu ataque de força bruta de senha. Se estiver testando um recurso de login, você pode fazer isso no Burp Suit com um ataque Pitchfork nas configurações (ou pode escrever seu próprio script para isso) para cada tentativa/série de tentativas.


Aqui está meu exemplo de como automatizei uma verificação simples do cabeçalho X-Forwarded-For apenas para obter um 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}")

Restaurando IPs de visitantes originais

Uma possível solução poderia ser a utilização da Cloudflare e seus mecanismos. Uma explicação detalhada pode ser encontrada aqui restaurando-original-visitor-ips . Fornecerei apenas uma breve visão geral dos seus mecanismos de defesa.


Se você usar aplicativos que dependem do endereço IP de entrada do visitante original, um endereço IP da Cloudflare será registrado por padrão. O endereço IP do visitante original aparece em um cabeçalho HTTP anexado chamado CF-Connecting-IP. Seguindo as instruções do nosso servidor web, você pode registrar o endereço IP do visitante original em seu servidor de origem. Se esse cabeçalho HTTP não estiver disponível quando as solicitações chegarem ao servidor de origem, verifique a configuração das regras de transformação e das transformações gerenciadas.


Se Pseudo IPv4 estiver definido como Overwrite Headers - a Cloudflare substitui os cabeçalhos Cf-Connecting-IP e X-Forwarded-For existentes por um endereço pseudo IPv4, preservando o endereço IPv6 real no cabeçalho CF-Connecting-IPv6.


NOTA: Lembre-se, ao implementar tal mecanismo de defesa, realize testes completos. Esta abordagem pode ser posteriormente aplicada a todo o cluster e pode afetar negativamente determinadas funções e microsserviços onde for desnecessário. Resumindo, ao corrigir uma violação de segurança, seja cauteloso, pois isso pode afetar potencialmente todo o aplicativo. Analise qual parte do seu sistema pode ser afetada negativamente e teste tudo antes de enviar as alterações para o ambiente de produção.


Também publicado aqui .