Cenários de Rate Limiting
Cenários de Uso: API Rate Limiting & Security Headers
O ForestWatch é uma plataforma SaaS de gestão florestal com endpoints de autenticação, validação de recursos e APIs de dados. Sem rate limiting, esses endpoints ficam vulneráveis a ataques de força bruta, enumeração de emails/slugs e abuso de recursos.
UC-1: Ataque de Força Bruta Bloqueado
Ator: Atacante tentando adivinhar credenciais
Endpoint: /api/auth/check-email
Tier: strict (5 req/60s)
Req 1 (0s): POST /api/auth/check-email → 200 OK, remaining: 4
Req 2 (0.5s): POST /api/auth/check-email → 200 OK, remaining: 3
Req 3 (1s): POST /api/auth/check-email → 200 OK, remaining: 2
Req 4 (1.5s): POST /api/auth/check-email → 200 OK, remaining: 1
Req 5 (2s): POST /api/auth/check-email → 200 OK, remaining: 0
Req 6 (2.5s): POST /api/auth/check-email → 429 Too Many Requests
→ Retry-After: 58
→ Bloqueado por ~58 segundos
Req N (62s): POST /api/auth/check-email → 200 OK, remaining: 4 ← Nova janelaResultado: Atacante limitado a 5 tentativas por minuto. Usuário legítimo raramente faz mais de 1-2 verificações por minuto.
Valor: Reduz drasticamente a viabilidade de ataques de força bruta sem impactar UX normal.
UC-2: Enumeração de Emails Mitigada
Ator: Atacante tentando descobrir emails cadastrados
Endpoint: /api/onboarding/validate-email
Tier: strict (5 req/60s)
O atacante consegue testar apenas 5 emails por minuto. Para enumerar 10.000 emails levaria ~33 horas (vs segundos sem proteção). Respostas genéricas não revelam detalhes sobre o estado do email.
Valor: Protege privacidade dos usuários e dificulta ataques de phishing direcionado.
UC-3: Enumeração de Slugs Prevenida
Ator: Atacante tentando descobrir nomes de equipes/projetos
Endpoints: /api/onboarding/validate-slug, /api/projects/validate-slug
Tier: standard (30 req/60s)
Tier standard permite 30 req/min (suficiente para uso normal de formulário). Atacante limitado a 1.800 tentativas por hora. Respostas genéricas não confirmam existência de organizações.
Valor: Protege informação competitiva sobre quais empresas usam a plataforma.
UC-4: Usuário Normal Não Afetado
Ator: Desenvolvedor usando a plataforma normalmente Endpoints: Vários com tier standard (30 req/60s) Padrão de uso: 2-5 requisições por minuto
Minuto 1: 3 requisições → remaining: 27, 26, 25
Minuto 2: 2 requisições → remaining: 28, 27 ← Nova janela
Minuto 3: 5 requisições → remaining: 25, 24, 23, 22, 21Resultado: Usuário nunca se aproxima do limite. Headers X-RateLimit-Remaining informam o estado atual. Experiência completamente transparente.
UC-5: Health Check com Tier Lenient
Ator: Sistema de monitoramento (UptimeRobot, Datadog, etc.)
Endpoint: /api/health
Tier: lenient (60 req/60s)
Padrão de uso: Ping a cada 30 segundos
2 req/min está muito abaixo do limite de 60 req/min. Mesmo com múltiplos monitores, o tier lenient acomoda facilmente.
Valor: Garante que monitoramento de uptime funciona sem interrupção.
UC-6: Webhooks Isentos de Rate Limiting
Ator: Stripe enviando webhooks de pagamento
Endpoints: /api/billing/webhook, /api/billing/stripe-webhook, /api/db/webhook
Rate Limit: Nenhum (isentos)
Webhooks nunca são bloqueados por rate limiting. Segurança garantida por verificação de assinatura HMAC (não por rate limit).
Valor: Pagamentos processados sem atraso. Sem risco de perder eventos de billing.
UC-7: Rate Limiting Desabilitado em Dev Local
Ator: Desenvolvedor em ambiente local
Configuração: RATE_LIMIT_DISABLED=true no .env.local
Todas as verificações de rate limit são puladas. Desenvolvimento e debugging sem fricção. Testes automatizados rodam sem interferência.
Valor: Produtividade do desenvolvedor não é impactada.
UC-8: Falha do Store Aciona Fail-Open
Ator: Sistema em produção com erro no store
Causa: Bug no InMemoryRateLimitStore ou erro de memória
1. Requisição chega ao enhanceRouteHandler
2. checkRateLimit() é chamado
3. store.check() lança exceção
4. Catch block captura o erro
5. Log: "[rate-limit] Erro no store, permitindo requisição"
6. Requisição continua normalmente para o handler
7. Resposta retornada sem headers de rate limitResultado: Aplicação continua funcionando mesmo com rate limiter quebrado. Erro logado para investigação.
Valor: Disponibilidade da aplicação não depende do rate limiter.
UC-9: Security Headers Protegem Contra Clickjacking
Ator: Atacante tentando embutir ForestWatch em iframe malicioso
Header: X-Frame-Options: DENY
<!-- Página maliciosa do atacante -->
<html>
<body>
<h1>Clique aqui para ganhar um prêmio!</h1>
<iframe src="https://app.forestwatch.com/settings/delete-account"
style="opacity: 0; position: absolute; top: 0;">
</iframe>
</body>
</html>Quando o usuário acessa a página maliciosa:
- Browser tenta carregar ForestWatch no iframe
- Resposta inclui
X-Frame-Options: DENY - Browser bloqueia o carregamento do iframe
- Ataque de clickjacking falha
Valor: Protege ações sensíveis contra clickjacking. Compliance com OWASP.
UC-10: Janela de Tempo Expira e Contador Reseta
Ator: Usuário que atingiu o limite e aguarda reset
Endpoint: /api/chat (tier standard: 30 req/60s)
Tempo 0s: Req 1 → allowed, remaining: 29
...
Tempo 25s: Req 30 → allowed, remaining: 0
Tempo 26s: Req 31 → BLOQUEADO, retryAfter: 34s
Tempo 50s: Req 33 → BLOQUEADO, retryAfter: 10s
--- Janela expira aos 60s ---
Tempo 61s: Req 34 → allowed, remaining: 29 ← Nova janela!Resultado: Após expiração da janela, contador reseta automaticamente. Header Retry-After informa exatamente quantos segundos aguardar.
Valor: Bloqueio é temporário. Experiência previsível e transparente.
Resumo dos Cenários
| UC | Cenário | Tier | Resultado |
|---|---|---|---|
| UC-1 | Força bruta em auth | strict | Bloqueado após 5 req/min |
| UC-2 | Enumeração de emails | strict | Limitado a 5 testes/min |
| UC-3 | Enumeração de slugs | standard | Limitado a 30 testes/min |
| UC-4 | Uso normal | standard | Sem impacto |
| UC-5 | Health check monitoring | lenient | Sem impacto |
| UC-6 | Webhooks Stripe | isento | Sempre permitido |
| UC-7 | Dev local | desabilitado | Sempre permitido |
| UC-8 | Falha do store | fail-open | Requisição permitida |
| UC-9 | Clickjacking | security headers | Iframe bloqueado |
| UC-10 | Reset de janela | qualquer | Contador reseta após windowMs |