Regra
Proteger contra lento regulares lentas.
As regulares com aninhados quantificadores ou
ambíguos padrões podem causar catastróficos
retrocesso e desempenho problemas.
Idiomas suportados: 45+Introdução
Expressões regulares podem congelar sua aplicação por segundos ou minutos com a entrada correta. O backtracking catastrófico ocorre quando os motores de regex exploram caminhos que aumentam exponencialmente ao tentar corresponder a um padrão. Uma regex como (a+)+b leva microssegundos para corresponder a uma entrada válida, mas pode levar horas para rejeitar uma sequência de 'a's sem um 'b' final. Atacantes exploram isso através de ataques de Negação de Serviço por Expressão Regular (ReDoS), enviando entradas maliciosas que fazem seu motor de regex consumir 100% da CPU até que ocorram timeouts de requisição ou o processo trave.
Por que isso importa
Implicações de segurança (ataques ReDoS): Um atacante pode paralisar sua aplicação com uma única requisição contendo uma entrada maliciosa. Padrões de validação de e-mail e análise de URL são alvos comuns. Ao contrário dos ataques DoS tradicionais que exigem largura de banda, o ReDoS precisa apenas de payloads minúsculos.
Degradação de desempenho: Entrada normal do usuário pode desencadear backtracking catastrófico, fazendo com que os tempos de resposta saltem de milissegundos para segundos. Isso cria uma latência imprevisível que é difícil de depurar porque só se manifesta com padrões de entrada específicos.
Incidentes de produção: Regex vulnerável bloqueia o event loop em Node.js ou consome recursos do pool de threads. À medida que as requisições se acumulam, a memória aumenta e o sistema se torna não responsivo. Em microsserviços, uma regex vulnerável propaga falhas para serviços dependentes.
Dificuldade na detecção: Padrões que funcionam bem em testes com entradas curtas tornam-se exponencialmente lentos com entradas mais longas. A vulnerabilidade muitas vezes passa despercebida até a produção, exigindo implantação de emergência durante um incidente ativo.
Exemplos de código
❌ Não-conforme:
function validateEmail(email) {
const regex = /^([a-zA-Z0-9_\-\.]+)+@([a-zA-Z0-9_\-\.]+)+\.([a-zA-Z]{2,5})$/;
return regex.test(email);
}
function extractURLs(text) {
const regex = /(https?:\/\/)?([\w\-])+\.(\w+)+([\w\-\.,@?^=%&:/~\+#]*)+/g;
return text.match(regex);
}
Por que é inseguro: Os quantificadores aninhados ([a-zA-Z0-9_\\-\\.]+)+ criar backtracking exponencial. Para um e-mail como aaaaaaaaaaaaaaaaaaaaaaaaa!, o motor de regex tenta inúmeras combinações antes de falhar. A regex de URL possui múltiplos quantificadores aninhados que agravam o problema, tornando-a trivialmente explorável com entradas como longas strings de caracteres válidos sem a estrutura esperada.
✅ Compatível:
function validateEmail(email) {
const regex = /^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-\.]+\.[a-zA-Z]{2,5}$/;
return regex.test(email);
}
function extractURLs(text) {
const regex = /https?:\/\/[\w\-]+\.[\w\-]+(?:[\w\-\.,@?^=%&:/~\+#]*)?/g;
return text.match(regex);
}
Por que é seguro: Remover quantificadores aninhados elimina o backtracking catastrófico. Quantificadores únicos como [a-zA-Z0-9_\-\.]+ são executados em tempo linear. O padrão de URL usa grupos não-capturantes com sufixo opcional (?:...)? em vez de repetição aninhada, garantindo desempenho previsível independentemente do comprimento ou conteúdo da entrada.
Conclusão
O desempenho de expressões regulares é uma preocupação de segurança, não apenas uma otimização. Revise todos os padrões de regex em busca de quantificadores aninhados, classes de caracteres sobrepostas em grupos de repetição e alternativas ambíguas. Teste os padrões de regex com entradas patológicas (longas cadeias de caracteres válidos seguidas por terminações inválidas) para identificar o backtracking catastrófico antes da implantação. Quando possível, substitua regex complexas por funções de análise de string que possuam características de desempenho previsíveis.
.avif)
