Valider les Expressions Régulières pour Prévenir le ReDoS
Découvrez comment valider les expressions régulières et sécuriser vos applications contre les attaques ReDoS (Regular Expression Denial of Service).

Les expressions régulières (regex) font partie des outils indispensables dans le développement logiciel moderne. Elles permettent de valider des formats de données, d'effectuer des recherches de motifs textuels complexes et de structurer des filtres en seulement quelques lignes de code. Cependant, cette grande flexibilité introduit un risque de sécurité majeur et souvent sous-estimé : le déni de service par expression régulière, ou attaque ReDoS (Regular Expression Denial of Service).
Contrairement aux attaques de déni de service distribuées (DDoS) qui nécessitent des réseaux de machines infectées (botnets) pour surcharger une bande passante, une attaque ReDoS peut être menée par un seul acteur malveillant envoyant une simple chaîne de caractères ciblée. Si votre application n'est pas configurée pour valider les expressions régulières de manière sécurisée, cette unique requête peut bloquer le processeur de votre serveur web, empêchant ainsi les utilisateurs légitimes d'accéder au site. Dans cet article, nous verrons comment fonctionnent les attaques ReDoS, comment se produit le backtracking catastrophique et comment protéger vos codes.
Qu'est-ce qu'une attaque ReDoS et comment se produit-elle ?
Une attaque ReDoS est une vulnérabilité de complexité algorithmique. Elle se produit lorsque le moteur d'expressions régulières d'un langage (comme JavaScript, Python, PHP ou Java) traite une chaîne de caractères spécialement conçue pour déclencher un temps d'exécution astronomique.
Le problème réside dans le fonctionnement interne des moteurs de regex de type NFA (Nondeterministic Finite Automaton). Ces moteurs parcourent la chaîne de caractères caractère par caractère. Lorsqu'un chemin de validation échoue, le moteur revient en arrière pour essayer d'autres combinaisons possibles. Si le modèle de regex est ambigu, ce processus de test et d'erreur augmente de façon exponentielle avec la longueur de la chaîne, un phénomène technique appelé backtracking catastrophique (retour sur trace catastrophique).
L'Anatomie du Backtracking Catastrophique
Pour comprendre comment le processeur peut être surchargé, prenons un motif regex très simple : ^(a+)+$
Cette expression cherche à valider une chaîne composée uniquement du caractère "a". Si l'on teste la chaîne "aaaa", la correspondance est immédiate. En revanche, que se passe-t-il si l'on envoie la chaîne "aaaaaaaaaaaaaaaaaaaaaaaaaaaaab" ? Le moteur valide tous les "a", puis cherche le "b" final. N'en trouvant pas, il commence à revenir en arrière pour tester toutes las combinaisons de découpage du motif imbriqué (a+)+ afin de s'assurer qu'aucune autre configuration ne correspond.
Le nombre de chemins testés croît de manière exponentielle en fonction de la longueur de la chaîne ($2^n$, où $n$ est le nombre de caractères "a").
Le schéma ci-dessous illustre le flux du backtracking catastrophique dans un moteur NFA :
[Chaîne d'entrée : "aaaaab"]
|
[Moteur Regex (NFA)]
|
+------------------+------------------+
| |
[Chemin 1: (aaaaa)b] [Chemin 2: (aaaa)(a)b]
(Échec sur 'b') (Échec sur 'b')
| |
[Retour en arrière] [Retour en arrière]
| |
[Chemin 3: (aaa)(aa)b] [Chemin 4: (aaa)(a)(a)b]
(Échec sur 'b') (Échec sur 'b')
| |
+------------------+------------------+
|
[Des millions d'autres combinaisons]
|
=======> [CPU à 100%]
Pour une chaîne de seulement 30 caractères, le nombre d'itérations dépasse le milliard, ce qui fige le thread d'exécution du serveur pendant plusieurs minutes.
Modèles Regex Vulnérables vs. Sécurisés
La structure classique exposant au ReDoS contient des quantificateurs imbriqués qui se chevauchent. Comparons des expressions courantes :
| Type de Validation | Motif Vulnérable (Risque ReDoS) | Motif Sécurisé Recommandé |
|---|---|---|
| Identifiants Simples | ^(a+)+$ |
^a+$ (pas de quantificateurs imbriqués) |
| Texte avec Espaces | ^(\w+\s?)*$ |
^\w+(\s\w+)*$ (élimine l'ambiguïté) |
| Validation Email (Simplifiée) | ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ (vulnérable aux boucles de points) |
^[a-zA-Z0-9]+([._+-][a-zA-Z0-9]+)*@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ |
| Numéros de Téléphone | ^(\+?[0-9-\s]+)*$ |
^\+?[0-9]{1,4}([- ]?[0-9]{1,15})*$ |
Comment Valider et Prévenir les Failles ReDoS dans votre Code
La prévention des attaques ReDoS doit être intégrée dès la phase de développement et d'architecture. Appliquez les bonnes pratiques suivantes :
1. Éviter les Quantificateurs Imbriqués et Ambigus
N'écrivez jamais de structures comme (a*)*, (a+)+ ou (a|b+)*. Si vous devez analyser des répétitions de motifs contenant des options, vérifiez que le moteur n'a pas plusieurs manières différentes de valider le même caractère.
2. Définir des Délais d'Attente Limites (Timeouts)
La plupart des langages de programmation modernes permettent de spécifier un temps d'exécution maximal pour l'évaluation d'une regex. Si ce temps de calcul est dépassé (par exemple, 100 millisecondes), le moteur lève une exception et interrompt le processus.
Voici comment implémenter des limites de temps de calcul en C# (.NET Core) pour bloquer le backtracking catastrophique :
using System;
using System.Text.RegularExpressions;
public class SecurityValidator
{
public static bool ValidateInput(string userInput)
{
// Définition d'un timeout strict de 100 millisecondes
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)
{
// L'exécution a dépassé le délai, suspicion de payload ReDoS
Console.WriteLine("Warning: L'exécution de la regex a dépassé la limite de temps autorisée.");
return false;
}
}
}
3. Privilégier les Moteurs de Regex Déterministes (DFA)
Si votre architecture logicielle le permet, utilisez des bibliothèques basées sur des moteurs DFA (comme Google re2). Ces moteurs effectuent l'analyse en temps linéaire par rapport a la taille de la chaîne, évitant ainsi mathématiquement tout risque de backtracking.
Pour tester la sécurité et la vitesse de vos motifs en temps réel, vous pouvez utiliser notre testeur d'expressions régulières. Cet outil en ligne vous permettra d'évaluer la rapidité de vos patterns et de corriger les faiblesses d'exécution.
Pour obtenir des détails approfondis sur la modélisation des automates finis et les approches de correction, consultez les guides techniques de l'organisation OWASP ReDoS Reference Guide. Vous pouvez également consulter notre guide sur la validation des expressions régulières sur TecnoCrypter pour concevoir des processus sécurisés.
Conclusion
Une expression régulière mal conçue peut suffire à mettre hors service vos serveurs web. La validation de vos regex avant leur mise en production est une étape de cybersécurité essentielle pour éviter les pannes applicatives dues aux attaques ReDoS.
La mise en place de motifs simples, l'absence de quantificateurs ambigus et le contrôle des temps de calcul sont les clés pour neutraliser ce type de déni de service. Prenez le temps de revoir vos algorithmes de validation d'entrée ; la stabilité de votre infrastructure en dépend directamente.
Sources et lectures recommandées :
- OWASP ReDoS Prevention Cheat Sheet — Recommandations de sécurité officielles contre le ReDoS.
- Google RE2 Library — Moteur regex en temps linéaire sans retour sur trace.
- Article associé sur TecnoCrypter : Valider les Expressions Régulières en Développement


