Retour au blog
JWTauthentificationAPIsessionsjetons

JWT : les failles d'expiration et de signature à tester

Publié le 2026-06-03 · Mis à jour le 2026-10-294 min de lecture
En bref : Un JWT est un jeton signé que le serveur accepte sans consulter de base. Cette propriété transforme chaque erreur en faille : un jeton sans expiration reste valable pour toujours une fois volé, un serveur qui accepte alg: none ou confond les algorithmes accepte des jetons forgés, et un secret HMAC faible se casse hors ligne. Voici comment ces failles s'exploitent, comment les tester en une heure et comment les corriger.

Pourquoi les JWT sont fragiles par construction

Un JWT contient trois parties encodées en base64url : un en-tête (algorithme, identifiant de clé), un contenu (identifiant, organisation, rôle, expiration) et une signature. Le serveur vérifie la signature puis fait confiance au contenu. Il n'y a pas de session côté serveur à invalider. Tant que la signature est valide et que la date d'expiration n'est pas passée, le jeton fonctionne. Toute la sécurité repose donc sur trois choses : la vérification stricte de la signature, la durée de vie du jeton et le secret de la clé.

Faille 1 : des jetons qui n'expirent pas

On trouve encore des jetons d'accès valables 30 jours, ou sans champ exp. Un jeton volé par XSS, dans un journal applicatif, un outil de support ou une capture d'écran donne alors un accès durable. Changer le mot de passe de la victime ne change rien : le jeton reste valide.

Correction : jetons d'accès de 5 à 15 minutes, jeton de rafraîchissement à usage unique avec rotation, et détection de la réutilisation d'un ancien jeton de rafraîchissement (signe de vol) qui révoque toute la famille.

Faille 2 : alg none et confusion d'algorithme

Deux attaques classiques visent la vérification :

  • `alg: none` : l'attaquant modifie le contenu ("role": "admin"), met l'algorithme à none et supprime la signature. Une bibliothèque mal configurée accepte le jeton.
  • Confusion RS256 / HS256 : le serveur signe en RS256 (clé privée, clé publique pour vérifier). L'attaquant forge un jeton en HS256 en utilisant la clé publique comme secret HMAC. Si le code vérifie avec « la clé » sans imposer l'algorithme, la signature passe.

Correction : imposez la liste des algorithmes acceptés côté serveur (algorithms: ['RS256']), ne lisez jamais l'algorithme depuis l'en-tête du jeton, et vérifiez iss, aud et exp.

Faille 3 : un secret HMAC faible

Un jeton HS256 signé avec secret, changeme ou le nom du produit se casse hors ligne : il suffit d'un seul jeton valide, et hashcat (mode 16500) teste des millions de candidats par seconde. Une fois le secret trouvé, l'attaquant émet des jetons pour n'importe quel compte. Une clé vide pose le même problème, comme l'a montré la faille JFrog Artifactory sur une clé de signature vide.

Correction : secret aléatoire d'au moins 256 bits stocké dans un gestionnaire de secrets, ou signature asymétrique avec rotation via JWKS.

Faille 4 : le jeton dans localStorage

Tout script exécuté sur la page lit localStorage. Une seule faille XSS, y compris dans une dépendance tierce, suffit à exfiltrer le jeton vers un serveur externe. Correction : jeton de rafraîchissement dans un cookie HttpOnly; Secure; SameSite=Strict, jeton d'accès en mémoire, et une politique CSP stricte.

Faille 5 : des claims trop bavards ou mal vérifiés

Le contenu d'un JWT est lisible par n'importe qui : c'est de l'encodage, sans chiffrement. Y mettre e-mail, salaire ou département expose ces données dans les journaux et les outils de support. À l'inverse, certaines API lisent l'org_id ou le rôle dans le jeton sans vérifier qu'ils sont toujours valides : un utilisateur rétrogradé garde ses droits jusqu'à l'expiration. Gardez des claims minimaux et revérifiez les droits sensibles côté serveur.

Comment le tester

  1. Décodez un jeton de votre application (jwt.io ou jwt_tool) : notez alg, exp, iat et la durée de vie réelle.
  2. Testez l'expiration : rejouez un jeton après sa date exp et après une déconnexion. Les deux requêtes doivent renvoyer 401.
  3. Testez `alg: none` : jwt_tool <jeton> -X a génère les variantes. Modifiez un claim de rôle et envoyez-les.
  4. Testez la confusion d'algorithme : récupérez la clé publique (souvent sur /.well-known/jwks.json) et lancez jwt_tool <jeton> -X k -pk public.pem.
  5. Testez la force du secret si l'algorithme est HS256 : hashcat -m 16500 jeton.txt wordlist.txt. Un secret trouvé en quelques minutes est une faille critique.
  6. Testez la signature : modifiez un caractère du contenu sans resigner. Le serveur doit refuser.
  7. Testez la réutilisation d'un jeton de rafraîchissement déjà utilisé : il doit être refusé et la session entière révoquée.
  8. Cherchez le jeton dans localStorage, les URL et les journaux front.

Ce que ça change quand un agent IA utilise ces jetons

Un agent IA qui appelle votre API reçoit souvent un jeton longue durée, parfois copié dans son contexte ou dans les traces de ses appels d'outils. Une injection de prompt peut lui faire répéter ce jeton dans une réponse, un ticket ou une requête vers un domaine contrôlé par l'attaquant. Donnez à l'agent des jetons courts, limités aux actions nécessaires, et injectés par l'environnement d'exécution plutôt que par le prompt. Les autres erreurs d'authentification sont détaillées dans notre article sur les failles JWT, OAuth et sessions.

Pour vérifier ce qu'un agent manipulé peut faire avec les jetons de votre produit, le Red Team Agent Express teste ces scénarios en cinq jours, preuves à l'appui.

Votre produit embarque un agent IA ? CleanIssue teste ce qu’un inconnu peut lui faire faire avec le Red Team Agent Express (5 jours, 1 900 €), ou un red team sur mesure pour plusieurs agents et serveurs MCP. Premier échange : un rendez-vous découverte de 30 minutes, gratuit.

Sachez ce que votre agent peut faire avant un attaquant.

Rendez-vous découverte de 30 minutes, gratuit : vous décrivez votre agent, je vous dis ce que je testerais et à quel prix. Cinq études de cas sont publiées.

Prendre rendez-vous