Regex chaîne Base64
L'auteur de la question de référence sur Stack Overflow a fini par publier sa propre regex dans une mise à jour de la question — mais un commentaire (7 votes) signale qu'elle contient une vraie faute de frappe : le « ^ » de début de chaîne ne porte que sur la première branche d'une alternation, laissant les deux autres sans ancrage. Notre analyse va plus loin : ce motif est vulnérable au ReDoS (complexité polynomiale), vérifié concrètement — une chaîne d'environ 95 000 caractères, presque entièrement des « = », bloque le moteur JavaScript pendant plus de 2 secondes. Le correctif « simplifié » suggéré dans le même commentaire a lui aussi un défaut réel : un tiret oublié dans la classe de caractères (un caractère du Base64 URL-safe, pas du Base64 standard) et aucune vérification que le nombre de « = » correspond au nombre de caractères qui précèdent. Voici un motif sûr et conforme à la RFC 4648, comparé à ces deux tentatives et à l'approche « je vérifie juste que chaque caractère est valide » que la question décrit elle-même comme fonctionnant dans 99% des cas.
/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/Comparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — regex publiée par l'auteur de la question lui-même, alternation dont le « ^ » ne porte que sur la première branche (bug signalé en commentaire) | ^[-A-Za-z0-9+/=]|=[^=]|={3,}$ | 9 / 20 | vulnérable ( ===========================================================…) |
| Stack Overflow — correctif « simplifié » suggéré en commentaire, tiret oublié dans la classe (Base64 URL-safe) et aucune vérification du nombre de « = » | ^[-A-Za-z0-9+/]*={0,3}$ | 13 / 20 | sûr |
| Stack Overflow — approche décrite dans le corps de la question elle-même comme fonctionnant « dans 99% des cas », vérifie seulement que chaque caractère est valide | ^[A-Za-z0-9+/=]+$ | 11 / 20 | sûr |
Implémentation
const re = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", "");
re.test(input);Limites
- Valide uniquement la FORME (alphabet et structure de remplissage) : une chaîne peut être syntaxiquement un Base64 valide sans pour autant décoder vers des données cohérentes ou exploitables.
- Ne couvre que l'alphabet Base64 standard (« + » et « / ») : la variante URL-safe (RFC 4648 §5, qui remplace ces deux caractères par « - » et « _ » et omet généralement le remplissage) nécessite un motif différent.
- Accepte la chaîne vide comme un Base64 valide (zéro octet de données) : selon le contexte d'utilisation, ce cas limite peut nécessiter un rejet explicite en dehors de la regex elle-même.
- N'impose aucune limite de longueur : une chaîne de plusieurs millions de caractères, si sa structure est correcte, reste acceptée — à combiner avec un contrôle de taille séparé si la donnée décodée doit rester bornée.