JWT
2 outils
Fondamentaux de la sécurité Web
La sécurité Web est la pratique consistant à protéger les applications Web et les API contre les accès non autorisés, les violations de données et les attaques. Les applications modernes utilisent l'authentification (prouver qui vous êtes), l'autorisation (prouver ce que vous pouvez faire) et la cryptographie pour définir les frontières de sécurité.
Les JSON Web Tokens (JWT) sont le mécanisme d'authentification sans état dominant dans le développement Web moderne. Comprendre leur structure, leurs algorithmes de signature et leurs vulnérabilités est essentiel pour concevoir des API et des applications sécurisées.
JSON Web Tokens (JWT)
Un JWT est un moyen compact et sécurisé pour les URL de représenter des revendications entre deux parties. Il se compose de trois parties encodées en Base64url séparées par des points. Les JWT peuvent être vérifiés sans requête en base de données car la signature couvre l'intégralité du token. Ils sont notamment utilisés comme tokens d'accès dans les flux OAuth2 et comme tokens d'identité dans OpenID Connect.
Les trois parties d'un JWT
Contient les métadonnées du token : l'algorithme de signature (alg) et le type de token (typ). Toujours encodé en Base64url. Le choix de l'algorithme dans cet en-tête conditionne la sécurité de l'ensemble du token.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9{
"alg": "HS256",
"typ": "JWT"
}Contient les revendications : déclarations sur l'utilisateur et métadonnées supplémentaires. Les données du payload ne sont PAS chiffrées, seulement signées — n'importe qui peut les lire. Outre les revendications standard, vous pouvez inclure des revendications privées spécifiques à votre application, comme le rôle ou les permissions de l'utilisateur.
eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzIwMDAwMH0{
"sub": "user_123",
"role": "admin",
"exp": 1717200000
}Une signature cryptographique sur l'en-tête et le payload encodés. La vérification garantit que le token n'a pas été altéré. La clé secrète (HMAC) ou la clé privée (RSA/ECDSA) n'est jamais incluse dans le token lui-même.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cHMACSHA256( base64url(header) + "." + base64url(payload), secret )
Revendications JWT standard
La spécification JWT définit des noms de revendications standard pour garantir l'interopérabilité entre différentes bibliothèques et services. Ces revendications dites « enregistrées » sont distinctes des revendications publiques (définies par IANA) et des revendications privées (propres à votre application). Utiliser les noms standard facilite l'intégration avec des bibliothèques tierces et des fournisseurs d'identité.
| Revendication | Nom | Description |
|---|---|---|
| iss | Issuer | Identifie le principal qui a émis le token (ex. : URL du serveur d'authentification) |
| sub | Subject | Identifie le principal qui est le sujet du token (ex. : ID utilisateur) |
| aud | Audience | Identifie les destinataires pour lesquels le token est destiné (ex. : URL de votre API) |
| exp | Expiration | Timestamp Unix après lequel le token ne doit plus être accepté |
| nbf | Not Before | Timestamp Unix avant lequel le token ne doit pas être accepté |
| iat | Issued At | Timestamp Unix auquel le token a été émis — utilisé pour déterminer son âge |
| jti | JWT ID | Identifiant unique du token, utilisé pour prévenir les attaques par rejeu |
Algorithmes de signature
L'algorithme de signature est déclaré dans l'en-tête JWT. Le bon choix est crucial pour la sécurité. Spécifiez toujours explicitement l'algorithme attendu lors de la vérification — ne laissez jamais la bibliothèque l'inférer depuis l'en-tête du token.
HS256 / HS384 / HS512Symétrique (HMAC)Utilise une clé secrète partagée pour la signature et la vérification. Simple à implémenter, mais tous les services qui vérifient les tokens doivent connaître le secret, ce qui augmente la surface d'exposition en cas de compromission.
RS256 / RS384 / RS512Asymétrique (RSA)Utilise une clé privée pour signer et une clé publique pour vérifier. La clé privée ne quitte jamais le serveur d'authentification. Les services vérifiant les tokens peuvent télécharger la clé publique via un endpoint JWKS (JSON Web Key Set) standard.
ES256 / ES384 / ES512Asymétrique (ECDSA)Comme RSA mais avec des clés plus petites et une signature plus rapide. Offre une sécurité équivalente avec de meilleures performances.
"alg": "none"Non signé — DANGEREUXAucune signature. Un token avec alg:none n'a aucune garantie d'intégrité et peut être forgé par n'importe qui.
Flux d'authentification
- 1.L'utilisateur envoie son nom d'utilisateur et mot de passe au point de terminaison de connexion
- 2.Le serveur valide les identifiants contre la base de données utilisateurs
- 3.Le serveur signe un JWT avec les revendications utilisateur et l'expiration
- 4.Le client stocke le JWT (localStorage, cookie ou mémoire)
- 5.Le client envoie le JWT dans l'en-tête Authorization: Bearer pour les requêtes suivantes
- 1.Le client redirige l'utilisateur vers le serveur d'autorisation avec le défi de code
- 2.L'utilisateur s'authentifie et autorise l'application cliente
- 3.Le serveur d'authentification redirige avec un code d'autorisation à usage unique
- 4.Le client échange le code + vérificateur contre des tokens d'accès et de rafraîchissement
- 5.Le client utilise le token d'accès pour les appels API ; le token de rafraîchissement pour le renouvellement
Vulnérabilités JWT courantes
Les JWT sont sécurisés lorsqu'ils sont correctement implémentés. Voici les erreurs d'implémentation les plus courantes. Une défense en profondeur — combinant des durées d'expiration courtes, une validation stricte de l'algorithme et un stockage sécurisé des clés — réduit considérablement la surface d'attaque.
Certaines bibliothèques acceptent les tokens avec alg:none. Un attaquant peut modifier le payload et définir alg sur none pour forger n'importe quel JWT. Spécifiez toujours explicitement l'algorithme attendu lors de la vérification.
Si une bibliothèque est censée vérifier RS256 mais accepte HS256, un attaquant peut signer un token en utilisant la clé publique comme secret HMAC. La bibliothèque le vérifie avec succès. Verrouillez toujours l'algorithme attendu côté vérification.
Un JWT sans revendication exp, ou du code qui ne vérifie pas exp, permet une utilisation indéfinie des tokens même après déconnexion ou désactivation du compte. Définissez toujours des durées d'expiration courtes et validez la revendication exp.
Les payloads JWT sont encodés en Base64, pas chiffrés. Quiconque intercepte un JWT peut décoder et lire son contenu. Ne jamais stocker de mots de passe, numéros de carte bancaire ou autres secrets dans les revendications JWT.
Les JWT signés HMAC avec des secrets courts ou prévisibles peuvent être forcés hors ligne. Un attaquant qui obtient un JWT peut tester des milliards de clés par seconde. Utilisez des secrets aléatoires cryptographiquement sûrs d'au moins 256 bits.
Accepter des JWT sans vérifier la signature fait entièrement confiance au payload. C'est un bug critique qui permet à n'importe quel utilisateur de forger des revendications arbitraires. Toujours vérifier la signature avant de faire confiance à une revendication.
Questions fréquentes
Les JWT standard (JWS — JSON Web Signature) sont signés mais PAS chiffrés. Le payload est encodé en Base64url, ce qui est trivialement réversible — quiconque obtient un JWT peut lire son contenu. JWE (JSON Web Encryption) fournit un vrai chiffrement, mais est beaucoup moins courant dans la pratique.
Les tokens d'accès doivent être de courte durée : 5 à 60 minutes est typique. Les tokens à longue durée de vie sont dangereux car ils ne peuvent pas être révoqués sans liste de blocage. Utilisez des tokens de rafraîchissement — à durée de vie plus longue et stockés de façon sécurisée — pour obtenir de nouveaux tokens d'accès sans redemander les identifiants.
Les cookies HttpOnly sont l'option la plus sécurisée — inaccessibles au JavaScript, ils empêchent le vol par XSS. localStorage est vulnérable aux attaques XSS mais évite les problèmes CSRF. La mémoire (variable JavaScript) est la plus sûre mais ne survit pas à un rechargement de page. Il n'existe pas d'option parfaite — le choix dépend du profil de menace de votre application.
Pas sans état côté serveur. La nature sans état des JWT signifie que le serveur ne peut pas les invalider directement. Solutions possibles : des durées d'expiration courtes, une liste de blocage de tokens (Redis), des tokens de rafraîchissement rotatifs, ou le passage à des tokens de session opaques pour les opérations sensibles.
Les cookies de session stockent un ID de session aléatoire ; le serveur recherche les données de session en base de données. Les JWT sont autonomes — le serveur valide la signature sans requête de base de données. Les JWT passent mieux à l'échelle sur plusieurs serveurs, mais ne peuvent pas être révoqués sans infrastructure supplémentaire.
Le minimum : sub (ID utilisateur), exp (expiration) et iat (émis le). Ajoutez iss (émetteur) pour les architectures multi-services et aud (audience) pour restreindre l'usage du token à un service spécifique. Gardez les payloads petits — les JWT sont envoyés à chaque requête. N'incluez pas de données sensibles ni de grands objets de profil.
RS256 (asymétrique) est préférable pour la plupart des systèmes de production car seul le serveur d'authentification a besoin de la clé privée. Plusieurs services peuvent vérifier les tokens en utilisant la clé publique sans partager de secret, ce qui réduit le risque de compromission. HS256 est plus simple mais oblige tous les vérificateurs à connaître le secret partagé.
PKCE (Proof Key for Code Exchange) est une extension du flux de code d'autorisation OAuth2 qui empêche les attaques d'interception de code. Le client génère un vérificateur de code aléatoire et n'envoie que son empreinte cryptographique au début du flux — ce qui rend le code d'autorisation inutilisable s'il est intercepté. PKCE est obligatoire pour les clients publics (SPA, applications mobiles) qui ne peuvent pas stocker un secret client de façon sécurisée.