Sécurité des JSON Web Tokens : vulnérabilités courantes et corrections
Les JWT sont le standard de facto pour l'authentification API, mais leur simplicité apparente cache de véritables piÚges de sécurité. Des JWT mal configurés ont conduit à des contournements d'authentification, des élévations de privilÚges et des fuites de données. Ce guide couvre les vulnérabilités les plus critiques et comment les prévenir.
Rappel de la structure JWT
Un JWT se compose de trois parties encodées en Base64URL séparées par des points :
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.signature
- Header : Algorithme et type de token
- Payload : Claims (données utilisateur, expiration, etc.)
- Signature : Vérification cryptographique
Inspectez la structure JWT avec notre Encodeur/Décodeur JWT.
Pour une compréhension fondamentale de la structure JWT, consultez notre guide Les tokens JWT expliqués.
Vulnérabilités critiques
1. Attaque par confusion d'algorithme
La vulnérabilité JWT la plus dangereuse. Si un serveur accepte le header alg du token sans validation, un attaquant peut :
Attaque : Changer l'algorithme de RS256 (asymétrique) à HS256 (symétrique) et signer le token falsifié avec la clé publique du serveur :
// Attacker's forged token
header: { "alg": "HS256", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
// Signed with the server's PUBLIC key as the HMAC secret
Si le serveur vérifie les tokens HS256 en utilisant la clé publique comme secret, le token falsifié passe la vérification.
Correction : Toujours spécifier l'algorithme attendu explicitement :
// WRONG - accepts whatever algorithm the token specifies
jwt.verify(token, key);
// CORRECT - enforce specific algorithm
jwt.verify(token, key, { algorithms: ['RS256'] });
2. Attaque de l'algorithme None
Certaines bibliothĂšques acceptent "alg": "none" â un token sans signature :
// Forged token with no signature
header: { "alg": "none", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
signature: "" // empty
Correction : N'autorisez jamais l'algorithme none en production. Définissez explicitement la liste blanche des algorithmes autorisés.
3. Secrets de signature faibles
Les JWT basés sur HMAC (HS256/HS384/HS512) ne sont aussi forts que le secret :
// TERRIBLE - can be brute-forced in seconds
secret = "password123"
// WEAK - dictionary attack vulnerable
secret = "my-jwt-secret"
// STRONG - 256+ bits of randomness
secret = "a3f2b8c9d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0"
Correction : Utilisez au moins 256 bits d'alĂ©a cryptographique pour les secrets HMAC. Mieux encore, utilisez des clĂ©s asymĂ©triques (RS256, ES256) oĂč la clĂ© de signature n'a jamais besoin d'ĂȘtre partagĂ©e.
4. Expiration manquante
Les tokens sans expiration n'expirent jamais â un token volĂ© accorde un accĂšs permanent :
// WRONG - no expiration
{ "sub": "user123", "role": "admin" }
// CORRECT - short expiration
{
"sub": "user123",
"role": "admin",
"exp": 1705312800,
"iat": 1705309200,
"nbf": 1705309200
}
Bonne pratique : Les tokens d'accÚs expirent en 15 à 60 minutes. Utilisez des tokens de rafraßchissement (stockés de maniÚre sécurisée) pour les sessions longues.
5. Données sensibles dans le payload
Les payloads JWT sont encodés en Base64URL, pas chiffrés. N'importe qui peut les décoder :
echo "eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ" | base64 -d
# {"sub":"123","role":"admin"}
N'incluez jamais : Mots de passe, clés API, numéros de carte de crédit, données personnelles (numéro de sécurité sociale, dossiers médicaux) ou tout secret dans les payloads JWT.
6. Stockage des tokens (XSS vs CSRF)
| Stockage | Vulnérable XSS | Vulnérable CSRF |
|---|---|---|
| localStorage | Oui | Non |
| Cookie (sans flags) | Oui | Oui |
| Cookie HttpOnly | Non | Oui |
| Cookie HttpOnly + SameSite | Non | Non |
RecommandĂ© : Stockez les JWT dans des cookies HttpOnly, Secure, SameSite=Strict. Cela empĂȘche l'accĂšs JavaScript (dĂ©fense XSS) et les requĂȘtes cross-site (dĂ©fense CSRF).
Set-Cookie: token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600
Checklist de sécurité
- SpĂ©cifiez explicitement les algorithmes â n'acceptez jamais celui du header du token
- Rejetez l'algorithme
noneâ exigez toujours une signature - Utilisez des secrets forts â 256+ bits pour HMAC, 2048+ bits pour RSA
- DĂ©finissez une expiration courte â 15-60 minutes pour les tokens d'accĂšs
- Validez tous les claims â
exp,iss,aud,nbf - Stockez dans des cookies HttpOnly â pas dans localStorage
- Faites une rotation des secrets pĂ©riodiquement â planifiez la rotation des clĂ©s
- Ne stockez jamais de données sensibles dans le payload
- Utilisez des clés asymétriques pour les systÚmes distribués (RS256 ou ES256)
- ImplĂ©mentez la rĂ©vocation de tokens â liste noire ou expiration courte + tokens de rafraĂźchissement
Signature asymétrique vs. symétrique
| Aspect | HS256 (Symétrique) | RS256 (Asymétrique) |
|---|---|---|
| Clé | Secret partagé | Paire clé privée/publique |
| Qui peut signer | Quiconque possÚde le secret | Seul le détenteur de la clé privée |
| Qui peut vérifier | Quiconque possÚde le secret | Quiconque possÚde la clé publique |
| Distribution des clĂ©s | Le secret doit ĂȘtre partagĂ© de maniĂšre sĂ©curisĂ©e | Seule la clĂ© publique est partagĂ©e |
| Performance | Plus rapide | Plus lent |
| Idéal pour | Service unique | Microservices, systÚmes distribués |
Recommandation : Utilisez ES256 (ECDSA) pour les nouvelles applications â il offre la sĂ©curitĂ© asymĂ©trique avec des performances proches du HMAC.
Stratégies de révocation de tokens
Les JWT sont sans Ă©tat par conception â il n'y a pas de moyen intĂ©grĂ© de les rĂ©voquer. StratĂ©gies :
- Expiration courte : Si les tokens expirent en 15 minutes, la fenĂȘtre d'un token volĂ© est limitĂ©e
- Rotation des tokens de rafraĂźchissement : Ămettre un nouveau token de rafraĂźchissement Ă chaque utilisation ; si un token est utilisĂ© deux fois, rĂ©voquer tous les tokens
- Liste noire : Stocker les identifiants des tokens rĂ©voquĂ©s (claims jti) et vĂ©rifier Ă chaque requĂȘte
- Versioning des tokens : Inclure un numéro de version dans les claims ; incrémenter la version de l'utilisateur à la déconnexion
FAQ
Dois-je utiliser JWT ou les cookies de session pour l'authentification ?
Les cookies de session sont plus simples et plus sĂ©curisĂ©s pour les applications web traditionnelles â le serveur contrĂŽle le cycle de vie de la session, et la rĂ©vocation est instantanĂ©e. Les JWT sont meilleurs pour les API sans Ă©tat, les microservices et les applications mobiles oĂč le stockage de session cĂŽtĂ© serveur n'est pas pratique. Si vous choisissez les JWT, implĂ©mentez les mesures de sĂ©curitĂ© de ce guide.
Quel est le temps d'expiration idéal pour un JWT ?
Pour les tokens d'accÚs : 15-60 minutes. Plus court est plus sécurisé mais nécessite des rafraßchissements plus fréquents. Pour les tokens de rafraßchissement : 1-30 jours, stockés dans des cookies HttpOnly. Pour les tokens à usage unique (vérification d'e-mail, réinitialisation de mot de passe) : 1-24 heures.
Ressources associées
- Encodeur/DĂ©codeur JWT â Inspectez et dĂ©codez les JWT en toute sĂ©curitĂ©
- Les tokens JWT expliquĂ©s â Comprendre la structure et le flux JWT
- L'entropie des mots de passe expliquĂ©e â Robustesse des secrets de signature JWT