Cybreach Consulting Prendre RDV
Retour aux articles
Vulnérabilités

JWT : les erreurs d'implémentation qui exposent votre API

JSON Web Token est devenu le standard de facto pour l'authentification dans les APIs REST. Et avec lui, toute une famille de vulnérabilités que les scanners automatiques ratent systématiquement, parce qu'elles ne se trouvent pas dans une ligne de code, mais dans des choix d'implémentation qui semblent anodins jusqu'au jour où quelqu'un les regarde de près.

Ce qu'est un JWT, en une phrase

Un JWT est un jeton signé en trois parties séparées par des points : un header (algorithme et type), un payload (les données, user_id, role, exp…), et une signature. Le serveur émet le token après authentification, le client le stocke et le renvoie à chaque requête. Le serveur vérifie la signature pour s'assurer que le payload n'a pas été modifié en transit.

Ce mécanisme est solide en théorie. En pratique, les erreurs d'implémentation sont nombreuses, répandues, et souvent critiques, parce que le payload n'est qu'encodé en Base64, pas chiffré. N'importe qui peut le lire. Et si la vérification est mal faite, n'importe qui peut le forger.

Erreur 1 : L'algorithme none

La spécification JWT définit un algorithme spécial : none. Un token signé avec cet algorithme n'a pas de signature. Si le serveur accepte ce type de token, n'importe qui peut forger un token arbitraire : il suffit de modifier le payload ("role": "admin") et de déclarer "alg": "none" dans le header. La signature est absente, le serveur l'accepte.

Cette vulnérabilité était répandue dans les premières versions de bibliothèques JWT populaires, certaines versions de jsonwebtoken (Node.js) ou PyJWT (Python) étaient vulnérables par défaut. Les versions récentes corrigent le problème. Mais une dépendance non mise à jour, ou une configuration explicitement permissive, suffit à rouvrir la porte.

En pentest, la vérification est immédiate : modifier le header du token pour passer "alg": "none", supprimer la partie signature, et rejouer la requête. Si le serveur répond 200, il est vulnérable.

Erreur 2 : Secret faible ou prévisible

Lorsqu'un token est signé avec HMAC (HS256, HS384, HS512), la sécurité repose entièrement sur la robustesse du secret. Un secret faible, secret, password, changeme, le nom de l'application, la date de déploiement, peut être cassé par attaque par dictionnaire ou force brute.

Des outils comme hashcat permettent de tester des centaines de millions de candidats par seconde. Un seul token JWT valide suffit pour lancer l'attaque : l'attaquant n'a besoin d'aucun accès particulier au serveur, seulement d'intercepter un token en transit, ce qui arrive naturellement lors d'un pentest.

Un secret JWT doit avoir au minimum 256 bits d'entropie, généré de façon aléatoire. Jamais une chaîne lisible par un humain.

Erreur 3 : Confusion RS256 / HS256

C'est l'une des vulnérabilités JWT les plus subtiles. Elle apparaît lorsqu'un serveur utilise un algorithme asymétrique (RS256) mais accepte aussi les tokens signés avec HMAC (HS256).

En RS256, le serveur signe avec une clé privée et vérifie avec une clé publique. Cette clé publique est, par définition, accessible à tous, parfois exposée sur un endpoint /.well-known/jwks.json. Si le serveur accepte aussi HS256, un attaquant peut utiliser cette clé publique comme secret HMAC pour signer un token forgé. La bibliothèque utilisera la clé publique pour vérifier la signature HMAC, qui a précisément été créée avec cette même clé. La vérification passe.

La correction : ne jamais accepter plusieurs algorithmes côté serveur. Fixer explicitement l'algorithme attendu dans la configuration de vérification, et rejeter tout token dont le header déclare un algorithme différent.

Erreur 4 : Absence de validation des claims standards

Vérifier la signature ne suffit pas. Il faut aussi valider les claims standards du payload. Un token peut avoir une signature parfaitement valide et rester dangereux si ces vérifications sont absentes :

  • exp (expiration) : un token expiré doit être rejeté. Sans cette vérification, un token volé reste valide indéfiniment, même après une déconnexion ou un changement de mot de passe.
  • iss (issuer) : valider que le token a bien été émis par votre serveur, pas par un tiers qui utiliserait le même algorithme.
  • aud (audience) : dans une architecture microservices, vérifier que le token est destiné au bon service. Un token valide pour le service A ne doit pas être accepté par le service B.

Ce qu'on retient

Les vulnérabilités JWT ne se trouvent pas avec un scanner automatique. Elles nécessitent une compréhension du mécanisme et une revue manuelle de l'implémentation : quelle bibliothèque, quelle version, quelle configuration, quels algorithmes acceptés, quels claims validés. C'est précisément ce que couvre un pentest API, pas seulement les endpoints, mais la logique d'authentification qui les protège.

La règle la plus simple : utiliser une bibliothèque activement maintenue, fixer explicitement l'algorithme attendu, valider exp, iss et aud systématiquement, et générer les secrets avec un générateur cryptographique, jamais à la main.

Une question après la lecture ?

Vous utilisez des JWT dans votre application et vous avez un doute sur votre implémentation ? Envoyez un message. Pas de pitch, pas de devis automatique.

Ou réservez directement un cadrage de 30 minutes

Réserver un appel