🔥 Seu Regex Pode Estar Derrubando Seu Servidor (E Você Nem Sabe)
Sabe aquele regex "inocente" que você copiou do Stack Overflow ou até mesmo do chatgpt? Ele pode estar criando uma bomba relógio no seu código.
O Problema Silencioso: ReDoS
ReDoS (Regular Expression Denial of Service) é uma vulnerabilidade que pode congelar completamente sua aplicação com uma única string maliciosa. E o pior: é extremamente comum.
Um Exemplo Real
Olha esse regex aparentemente inofensivo para validar emails:
const emailRegex = /^(.+)*@(.+)*\.(com|org)$/;
emailRegex.test("aaaaaaaaaaaaaaaaaaaaaaaaaaX");
Resultado? Seu servidor vai congelar por vários segundos (ou minutos).
Por Que Isso Acontece?
Quando você usa quantificadores aninhados como (.+)*, o sistema do regex entra em um estado chamado "catastrophic backtracking" (backtracking catastrófico).
Em termos técnicos:
O regex tenta todas as combinações possíveis de matches, criando um crescimento exponencial de tentativas. Para uma string de 20 caracteres, podem ser milhões de tentativas.
Em termos simples:
É como se você pedisse para alguém encontrar uma agulha no palheiro, mas toda vez que a pessoa não encontra, você pede para ela reorganizar o palheiro de TODAS as formas possíveis e tentar de novo. Infinitamente.
O Impacto Real
Em um servidor Node.js, isso pode significar:
- Todas as requisições param de responder
- Timeout em todas as conexões
- CPU pode ir para até 100%
- Usuários recebem erro 504
Como Se Proteger?
1. Identifique Padrões Perigosos
// Quantificadores aninhados (mesmo sem alternação)
/(a+)+/
/(a*)*/
/([a-z]+)*/ // ← perigoso pelo + dentro do *
// Alternação sobreposta
/(a|aa)+/
/(a|a?)+/
// Grupos repetidos com wildcards
/(.*a){10}/ // ← explode se o "a" não existir
2. Simplifique Seus Regex
Antes (vulnerável):
/^(.+)*@(.+)*\.(com|org)$/
Depois (seguro):
/^[^@\s]{1,64}@[^@\s]{1,255}\.(com|org)$/
A diferença? Removemos os quantificadores aninhados (.+)* e substituímos os wildcards por classes de caracteres com limites explícitos, eliminando backtracking ambíguo e tornando o regex determinístico.
Entendendo a Matemática
Para os curiosos, o problema está no crescimento exponencial das tentativas:
Input: "aaaaaX"
Tentativas: 2^5 = 32
Input: "aaaaaaaaaaaaaaaaaaaaX" (20 caracteres)
Tentativas: 2^20 = 1.048.576
Input: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaX" (30 caracteres)
Tentativas: 2^30 = 1.073.741.824 (mais de 1 BILHÃO!)
Cada caractere adicional dobra o número de tentativas. É literalmente exponencial.
Casos Reais de ReDoS
Empresas e projetos que já sofreram com ReDoS:
- Stack Overflow (2016): Derrubado por 20 minutos
- Cloudflare (2019): Queda global por regex mal otimizado
Aproveitando a Deixa...
Depois de escrever esse post, percebi que ficar testando regex manualmente é um saco. Então criei uma ferramenta para automatizar isso.
Apresento: Resafe
Resafe é um detector matemático de vulnerabilidades ReDoS que analisa seus regex antes de você colocá-los em produção.
Como Funciona?
Ao invés de usar heurísticas ou "achismos", o Resafe usa matemática pura:
- Constrói um Autômato Finito (Thompson NFA) do seu regex
- Elimina transições vazias (epsilon transitions)
- Cria uma matriz de adjacência dos estados
- Calcula o raio espectral (maior autovalor da matriz)
Em termos simples:
Transforma seu regex em um grafo matemático e calcula se ele tem "loops infinitos" que causam explosão exponencial.
Se o raio espectral > 1.0, seu regex é vulnerável. Simples assim.
Instalação
npm install resafe
# ou
bun add resafe
Uso Básico
import { check } from "resafe";
// Validação simples
check(/([a-zA-Z0-9]+)*$/);
// Em produção (bloqueia regex inseguros)
try {
check("^[0-9]+$", {
throwErr: true,
silent: true
});
// Regex é seguro, pode usar
} catch (error) {
console.error("Regex bloqueado:", error.message);
}
// Análise programática
const result = check("(a+)+", { silent: true });
console.log(result.safe); // false
console.log(result.radius); // 4.0
Quer Saber Mais?
Conclusão
ReDoS é um problema real que afeta milhares de aplicações. A boa notícia? É totalmente evitável.
Três passos simples:
- Entenda o problema (você já fez isso lendo até aqui!)
- Identifique regex vulneráveis no seu código
- Use ferramentas como Resafe para automatizar a detecção
Não espere seu servidor cair em produção para descobrir que tinha um regex vulnerável. Previna agora.
Se esse post te ajudou, compartilha com seu time! E se encontrar um regex vulnerável no seu código (spoiler: você vai encontrar), conta aqui nos comentários.