Regex mot de passe robuste
La regex de mot de passe la plus copiée au monde (2,4k votes sur Stack Overflow) a un vrai défaut : sa liste blanche de caractères spéciaux rejette silencieusement tout mot de passe contenant une virgule, un point ou un signe non listé. Voici un motif qui exige les mêmes règles sans restreindre les caractères autorisés.
/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,}$/passe 20/20 cas
Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — réponse la plus votée au monde sur le sujet, 2,4k votes (Srinivas) | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$ | 15 / 20 | indéterminé |
| Stack Overflow — variante « simple » de la même réponse (lettres + chiffre seulement) | ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$ | 8 / 20 | indéterminé |
| Stack Overflow — réponse à 67 votes, non adaptée (plafond de 16 caractères conservé) | ^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\W)(?!.* ).{8,16}$ | 19 / 20 | indéterminé |
Implémentation
const re = new RegExp("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*\\W)(?!.* ).{8,}$", "");
re.test(input);Limites
- Valide seulement la forme (longueur + catégories de caractères), jamais la résistance réelle : « Passw0rd! » satisfait la règle mais reste un mot de passe trivial à deviner (dictionnaire + substitutions courantes).
- N'interdit que l'espace littéral : une tabulation ou un retour à la ligne collé par erreur passe silencieusement (voir le cas « Tab\tPass1! » du corpus).
- Aucune vérification contre une liste de mots de passe compromis (ex. Have I Been Pwned) — la seule protection réellement efficace selon NIST 800-63B, qu'une regex ne peut pas fournir.
- Le plafond de longueur a été volontairement retiré ({8,} au lieu de {8,16}) : un plafond bas rejette les phrases de passe longues, pourtant recommandées, sans bénéfice de sécurité réel.