Como Validar Expressões Regulares e Evitar Ataques ReDoS
Aprenda a validar expressões regulares e proteger seus sistemas contra ataques ReDoS (Regular Expression Denial of Service) usando boas práticas.

As expressões regulares (regex) são ferramentas essenciais no dia a dia do desenvolvimento de software. Elas facilitam a busca de padrões, a substituição de textos complexos e a validação de dados informados por usuários com poucas linhas de código. Contudo, a flexibilidade dessa tecnologia traz consigo um risco severo de segurança que costuma ser negligenciado: os ataques ReDoS (Regular Expression Denial of Service).
Diferente de um ataque DDoS (Distributed Denial of Service) tradicional, que exige redes massivas de computadores zumbis para congestionar a largura de banda de um servidor, um ataque ReDoS necessita de apenas um único atacante enviando uma cadeia curta de texto específica. Se o seu sistema não estiver configurado para validar expressões regulares de modo seguro, essa simples requisição pode elevar a utilização da CPU do servidor para 100%, paralisando completamente o atendimento a outros usuários. Neste artigo, detalharemos o funcionamento de ataques ReDoS, o comportamento do backtracking catastrófico e como proteger seu código de maneira eficiente.
O que é um ataque ReDoS e como ele ocorre?
O ataque ReDoS constitui uma vulnerabilidade baseada na complexidade de tempo do algoritmo. Ele ocorre quando o interpretador de expressões regulares utilizado por uma linguagem de programação (como JavaScript, Python, PHP ou Java) depara-se com uma entrada de texto projetada para exigir um número exorbitante de operações para ser processada.
A raiz dessa suscetibilidade está nos motores de busca do tipo NFA (Nondeterministic Finite Automaton). Tais motores processam a cadeia de entrada caractere por caractere. Quando um caminho de validação falha no meio do processo, o motor retorna posições para avaliar caminhos alternativos. Se o padrão regex for ambíguo, esse mecanismo de tentativa e erro se repete de forma exponencial à medida que a string de entrada cresce, gerando o chamado backtracking catastrófico.
Anatomia do Backtracking Catastrófico
Para visualizar esse gargalo operacional, consideremos o seguinte padrão regex simples: ^(a+)+$
Essa expressão tem o objetivo de verificar se uma string contém somente a letra "a". Caso o texto informado seja "aaaa", a validação é imediata. Mas o que ocorre quando passamos o texto "aaaaaaaaaaaaaaaaaaaaaaaaaaaaab"? O motor de busca valida todas as letras "a" iniciais e, ao tentar validar o caractere "b" no final, falha. Para certificar-se de que não há nenhuma outra combinação válida, ele começa a recuar e testar todas as possibilidades de divisão do padrão repetitivo (a+)+.
A quantidade total de caminhos testados cresce de forma exponencial de acordo com a extensão da string ($2^n$, onde $n$ é a quantidade de caracteres "a").
O diagrama abaixo ilustra o fluxo de processamento de um motor NFA sob ataque:
[String de entrada: "aaaaab"]
|
[Motor Regex (NFA)]
|
+------------------+------------------+
| |
[Tentativa 1: (aaaaa)b] [Tentativa 2: (aaaa)(a)b]
(Falha no 'b') (Falha no 'b')
| |
[Recuo / Backtrack] [Recuo / Backtrack]
| |
[Tentativa 3: (aaa)(aa)b] [Tentativa 4: (aaa)(a)(a)b]
(Falha no 'b') (Falha no 'b')
| |
+------------------+------------------+
|
[Milhões de caminhos adicionais]
|
=======> [CPU a 100%]
Para uma string de apenas 30 caracteres, o número de repetições internas ultrapassa a marca de um bilhão de iterações, bloqueando a execução da aplicação por vários minutos.
Comparativo de Padrões Regex: Vulneráveis vs. Seguros
A estrutura causadora do ReDoS geralmente envolve quantificadores repetitivos que se sobrepõem de forma ambígua. Abaixo, comparamos algumas validações frequentes:
| Validação Pretendida | Padrão Vulnerável (ReDoS) | Padrão Seguro Recomendado |
|---|---|---|
| Identificadores Simples | ^(a+)+$ |
^a+$ (remove quantificadores aninhados) |
| Texto com Espaços | ^(\w+\s?)*$ |
^\w+(\s\w+)*$ (elimina a ambiguidade de caminhos) |
| Email (Simplificado) | ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ (pode travar em sequências de pontos) |
^[a-zA-Z0-9]+([._+-][a-zA-Z0-9]+)*@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ |
| Números de Telefone | ^^(\+?[0-9-\s]+)*$ |
^\+?[0-9]{1,4}([- ]?[0-9]{1,15})*$ |
Como Validar e Mitigar Falhas ReDoS no Desenvolvimento
A defesa eficaz contra o ReDoS começa na etapa de design e arquitetura do código da aplicação. Recomenda-se adotar as seguintes práticas:
1. Evitar Quantificadores Sobrepostos ou Aninhados
Evite escrever expressões como (a*)*, (a+)+ ou (a|b+)*. Ao modelar regras de validação para textos com repetições, garanta que não haja caminhos concorrentes ou ambíguos para validar o mesmo caractere.
2. Implementar Limites de Tempo (Timeouts) Estritos
A maior parte dos ambientes de programação modernos oferece suporte para definir um tempo de expiração para a validação de regex. Se a verificação exceder o limite (por exemplo, 100 milissegundos), o motor interrompe o processo lançando uma exceção.
Abaixo, demonstramos a implementação de limites de execução em C# (.NET Core) para conter o backtracking catastrófico:
using System;
using System.Text.RegularExpressions;
public class SecurityValidator
{
public static bool ValidateInput(string userInput)
{
// Define um limite de tempo estrito de 100 milissegundos
TimeSpan timeout = TimeSpan.FromMilliseconds(100);
string safePattern = @"^[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*$";
try
{
return Regex.IsMatch(userInput, safePattern, RegexOptions.None, timeout);
}
catch (RegexMatchTimeoutException)
{
// O tempo de processamento excedeu o limite seguro, provável payload ReDoS
Console.WriteLine("Warning: A validação da expressão regular excedeu o tempo máximo permitido.");
return false;
}
}
}
3. Empregar Motores de Busca Determinísticos (DFA)
Sempre que a infraestrutura permitir, utilize motores baseados em DFA (como a biblioteca re2 da Google). Motores DFA analisam a entrada em tempo linear em relação ao tamanho do texto de entrada, inviabilizando matematicamente o backtracking catastrófico.
Para validar suas regras de regex e testar a velocidade das suas expressões em tempo real, utilize o nosso testador de expressões regulares. Esta ferramenta ajuda a identificar problemas de lentidão e refinar a segurança dos seus padrões.
Para obter mais detalhes sobre a teoria dos autômatos e guias de modelagem segura, consulte as documentações oficiais da organização internacional OWASP ReDoS Reference Guide. Você também pode verificar o nosso artigo prático sobre como validar expressões regulares no portal TecnoCrypter para aprimorar suas rotinas de desenvolvimento.
Conclusión
Expressões regulares ineficientes podem expor seu backend a indisponibilidades críticas. Validar seus padrões de regex antes de implantá-los em ambiente de produção não é apenas um ajuste de performance, mas sim um passo de segurança indispensável para neutralizar ataques ReDoS de maneira definitiva.
A definição de padrões lineares, a eliminação de redundâncias e o monitoramento de timeouts impedem que requisições maliciosas afetem o desempenho de seus servidores. Dedique tempo a auditar suas validações de entrada; a estabilidade da sua infraestrutura depende da clareza e eficiência de suas expressões.
Fontes e leituras recomendadas:
- OWASP ReDoS Prevention Cheat Sheet — Guia padrão da OWASP para conter vulnerabilidades de expressões regulares.
- Google RE2 Library — Biblioteca oficial do motor regex linear sem backtracking catastrófico.
- Post relacionado no TecnoCrypter: Validar Expressões Regulares no Desenvolvimento


