Rexact
Cheatsheet

Regex JWT (JSON Web Token)

A Stack Overflow question's author wanted to mask JWTs in their logs, but their regex captured "any string with two dots" - including unrelated URL parameters. Worse: our ReDoS analysis flags it as vulnerable (polynomial complexity), a serious flaw for a regex meant to run on log lines an attacker could influence. An answer fixes the scope issue by requiring the first two segments to start with "eyJ" (the Base64URL start of '{"')... but a comment rightly points out that not every JWT necessarily starts with "eyJ". Here's a safe pattern that checks the real structure (3 Base64URL segments with no "=" padding), compared against both of those attempts and a third, more permissive one that also accepts a JWE's 5-segment form.

/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*$/
passes 20/20 cases

Comparison of existing patterns

SourcepatternScore on the corpusReDoS
Stack Overflow — regex de l'auteur de la question, démontrée dans la question elle-même comme capturant n'importe quelle chaîne à deux points[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*12 / 20vulnerable (------------------------------------------------------------…)
Stack Overflow — réponse à 3 votes, exige le préfixe littéral « eyJ » (signalé en commentaire comme non garanti pour tout JWT), et hérite du point erroné de la question dans la classe du 3e segment^eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_.+/]*$15 / 20safe
Stack Overflow — réponse étendue, accepte aussi la forme à 5 segments d'un JWE (trop permissif pour une validation JWS à 3 segments)^e[yw][A-Za-z0-9-_]+\.(?:e[yw][A-Za-z0-9-_]+)?\.[A-Za-z0-9-_]{2,}(?:(?:\.[A-Za-z0-9-_]{2,}){2})?$15 / 20safe

Implementation

const re = new RegExp("^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*$", "");
re.test(input);

Limits

  • Valide uniquement la FORME (3 segments Base64URL séparés par des points, sans remplissage « = ») : ne décode ni ne vérifie qu'un segment contient réellement du JSON valide, et encore moins que la signature correspond à la clé attendue.
  • Scope limité à la sérialisation compacte JWS (3 segments) : le format JWE (chiffrement, 5 segments) suit une structure différente et n'est pas couvert par ce motif.
  • Le troisième segment (signature) est autorisé à être vide pour couvrir le cas valide « alg: none » (JWT non signé, RFC 7515) : dans un contexte où seuls des tokens signés sont acceptables, ce cas devrait être rejeté séparément, en dehors de la regex elle-même.
  • N'impose aucune contrainte sur la longueur des segments : un JWT syntaxiquement valide selon ce motif peut être arbitrairement court et ne représenter aucune donnée exploitable une fois décodé.