ToolDeck

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

Header

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.

Encodé
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Décodé
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload

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.

Encodé
eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzIwMDAwMH0
Décodé
{
  "sub": "user_123",
  "role": "admin",
  "exp": 1717200000
}
Signature

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.

Encodé
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Décodé
HMACSHA256(
  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é.

RevendicationNomDescription
issIssuerIdentifie le principal qui a émis le token (ex. : URL du serveur d'authentification)
subSubjectIdentifie le principal qui est le sujet du token (ex. : ID utilisateur)
audAudienceIdentifie les destinataires pour lesquels le token est destiné (ex. : URL de votre API)
expExpirationTimestamp Unix après lequel le token ne doit plus être accepté
nbfNot BeforeTimestamp Unix avant lequel le token ne doit pas être accepté
iatIssued AtTimestamp Unix auquel le token a été émis — utilisé pour déterminer son âge
jtiJWT IDIdentifiant 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.

Utiliser quand : Services internes où toutes les parties sont contrôlées. Ne jamais utiliser quand des tiers doivent vérifier les tokens.
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.

Utiliser quand : Architectures de microservices, vérification de tokens tiers, OAuth2 et OpenID Connect.
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.

Utiliser quand : Applications mobiles et IoT où la performance est importante. Alternative moderne à RSA.
"alg": "none"Non signé — DANGEREUX

Aucune signature. Un token avec alg:none n'a aucune garantie d'intégrité et peut être forgé par n'importe qui.

Utiliser quand : Ne jamais utiliser en production. Certaines bibliothèques JWT ont historiquement accepté alg:none, ce qui a conduit à des vulnérabilités critiques.

Flux d'authentification

Flux par mot de passe (direct)
  1. 1.L'utilisateur envoie son nom d'utilisateur et mot de passe au point de terminaison de connexion
  2. 2.Le serveur valide les identifiants contre la base de données utilisateurs
  3. 3.Le serveur signe un JWT avec les revendications utilisateur et l'expiration
  4. 4.Le client stocke le JWT (localStorage, cookie ou mémoire)
  5. 5.Le client envoie le JWT dans l'en-tête Authorization: Bearer pour les requêtes suivantes
Code d'autorisation + PKCE (OAuth2)
  1. 1.Le client redirige l'utilisateur vers le serveur d'autorisation avec le défi de code
  2. 2.L'utilisateur s'authentifie et autorise l'application cliente
  3. 3.Le serveur d'authentification redirige avec un code d'autorisation à usage unique
  4. 4.Le client échange le code + vérificateur contre des tokens d'accès et de rafraîchissement
  5. 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.

Confusion d'algorithme (alg:none)Critique

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.

Confusion HS256/RS256Critique

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.

Validation d'expiration manquanteÉlevé

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.

Données sensibles dans le payloadÉlevé

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.

Clés secrètes faibles (HS256)Moyen

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.

Vérification de signature manquanteMoyen

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 sont-ils chiffrés ?

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.

Combien de temps un JWT doit-il être valide ?

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.

Où stocker les JWT dans le navigateur ?

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.

Puis-je révoquer un JWT avant son expiration ?

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.

Quelle est la différence entre JWT et les cookies de session ?

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.

Quelles revendications inclure dans un JWT ?

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 est-il meilleur que HS256 ?

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é.

Qu'est-ce que PKCE et pourquoi est-ce important ?

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.