Security
12 min read
3493 views

Confusion d'algorithme JWT : transformer des tokens RS256 en désastres HS256 🔄

IT
InstaTunnel Team
Published by our engineering team
Confusion d'algorithme JWT : transformer des tokens RS256 en désastres HS256 🔄

Comprendre la faille de sécurité critique qui transforme les clés publiques en secrets

Dans le paysage de la sécurité des applications web modernes, JSON Web Tokens (JWTs) sont omniprésents pour gérer l’authentification et l’autorisation. Cependant, une vulnérabilité subtile mais dévastatrice se cache dans de nombreuses implémentations JWT : les attaques de confusion d’algorithme. Ce vecteur d’attaque exploite la façon dont les serveurs valident les signatures JWT, permettant aux attaquants de forger des tokens en manipulant l’algorithme spécifié dans l’en-tête du token.

Qu’est-ce que la confusion d’algorithme JWT ?

Les vulnérabilités de confusion d’algorithme apparaissent généralement en raison d’une implémentation défectueuse des bibliothèques JWT, où beaucoup offrent une seule méthode, indépendante de l’algorithme, pour vérifier les signatures. La vulnérabilité survient lorsque le serveur ne force pas correctement l’algorithme cryptographique à utiliser pour vérifier la signature d’un JWT.

La confusion d’algorithme se produit lorsqu’un système ne vérifie pas correctement le type de signature utilisé dans un JWT, permettant à un attaquant d’exploiter une distinction insuffisante entre différentes méthodes de signature. La variante la plus dangereuse consiste à passer d’un RS256 (RSA avec SHA-256, un algorithme asymétrique) à un HS256 (HMAC avec SHA-256, un algorithme symétrique).

La différence fondamentale entre RS256 et HS256

Comprendre la confusion d’algorithme nécessite de saisir la différence fondamentale entre cryptographie symétrique et asymétrique :

RS256 (RSA + SHA-256) - Asymétrique : - Utilise une clé privée pour signer les tokens - Utilise une clé publique mathématiquement liée pour vérifier - La clé privée doit rester secrète - La clé publique peut être partagée ouvertement - Deux clés différentes pour deux usages distincts

HS256 (HMAC + SHA-256) - Symétrique : - Utilise une clé secrète unique pour signer et vérifier - La même clé effectue les deux opérations - La clé secrète doit rester confidentielle - Toute personne disposant de la clé peut créer et vérifier des tokens

Comment fonctionne l’attaque : le changement fatal

La variante la plus courante consiste à échanger un token RS256 contre un HS256, puis à utiliser la clé publique RSA comme secret HMAC. Voici le déroulement de l’attaque :

Étape 1 : Obtenir un JWT valide

L’attaquant obtient d’abord un JWT légitime de l’application, généralement signé avec RS256 :

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZSI6InVzZXIifQ.signature

Ce token comporte trois parties : - En-tête : {"alg":"RS256","typ":"JWT"} - Charge utile : {"sub":"user123","role":"user"} - Signature : Vérifiée avec la clé RSA publique du serveur

Étape 2 : Récupérer la clé publique

Les serveurs exposent parfois leurs clés publiques sous forme d’objets JSON Web Key (JWK) via un endpoint standard (/jwks.json ou /.well-known/jwks.json). Les attaquants peuvent obtenir ces clés par plusieurs moyens :

  • Endpoints JWKS standards (/.well-known/jwks.json)
  • Documentation ou fichiers de configuration du serveur
  • Certificats SSL/TLS
  • Dérivation de clés à partir de plusieurs JWT capturés avec des outils comme jwt_forgery.py

Étape 3 : Modifier l’en-tête et la charge utile du token

L’attaquant modifie l’algorithme dans l’en-tête de RS256 à HS256 et change la charge utile pour augmenter ses privilèges :

{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "user123",
  "role": "admin"
}

Étape 4 : Signer avec la clé publique comme secret HMAC

La falsification de tokens consiste à signer la charge utile du token en utilisant la clé publique PEM comme clé HMAC. L’attaquant signe le token modifié avec HS256, en traitant la clé publique RSA du serveur comme secret HMAC.

Étape 5 : Le serveur accepte le token falsifié

Lorsque le serveur reçoit ce token malveillant, la vulnérabilité se manifeste dans la façon dont la méthode de vérification le traite :

Les problèmes apparaissent lorsque les développeurs pensent que la méthode verify ne traitera que des JWT signés avec un algorithme asymétrique comme RS256, en passant toujours une clé publique fixe.

// Exemple de code vulnérable
publicKey = clé-publique-du-serveur;
token = request.getCookie("session");
verify(token, publicKey);

Si le serveur reçoit un token signé avec un algorithme symétrique comme HS256, la méthode verify générique traitera la clé publique comme un secret HMAC. Le serveur utilise inconsciemment sa propre clé publique comme secret HMAC pour vérifier la signature de l’attaquant, qui sera validée avec succès car l’attaquant a utilisé la même clé publique pour créer la signature.

Impact réel : vulnérabilités récentes

La confusion d’algorithme n’est pas une menace purement théorique. Des découvertes récentes montrent sa prévalence continue :

CVE-2024-54150 (décembre 2024)

Une vulnérabilité a été découverte dans la bibliothèque cjwt où la fonction cjwt_decode ne requiert pas que les développeurs choisissent un algorithme, et le traitement des clés HMAC et RSA était identique. La structure switch de la bibliothèque traitait les tokens HS256 avec la clé fournie sans détecter qu’une clé publique était passée comme secret.

CVE-2024-37568 (2024)

Cette vulnérabilité critique dans Authlib, une bibliothèque Python populaire pour OAuth et OpenID Connect, est survenue lorsque la revendication ‘alg’ était manquante ou incorrecte, entraînant une mauvaise détection et une vérification HMAC par défaut, même en présence d’une clé publique.

CVE-2023-48238 (2023)

La bibliothèque json-web-token était vulnérable car l’algorithme utilisé pour vérifier la signature était extrait du JWT lui-même, qui n’était pas encore vérifié et ne devait pas être fiable.

Pourquoi cette vulnérabilité existe : causes profondes

Conception défectueuse des bibliothèques

L’en-tête JWT contient un paramètre alg qui indique à quel algorithme le serveur doit faire confiance pour signer et vérifier. Cela crée une conception intrinsèquement défectueuse car le serveur doit faire confiance à une entrée contrôlable par l’utilisateur, non vérifiée.

Mauvaise compréhension des développeurs

De nombreux développeurs sous-estiment les implications de sécurité des méthodes de vérification génériques. Ils pensent qu’en passant une clé publique, la bibliothèque n’acceptera que des signatures asymétriques, sans réaliser que la bibliothèque fait confiance à l’algorithme indiqué dans l’en-tête non vérifié.

Validation insuffisante

Les applications échouent souvent à valider que l’algorithme dans l’en-tête correspond à leur algorithme attendu. Sans cette vérification, les attaquants peuvent substituer des algorithmes à volonté.

Démonstration de l’attaque : exploitation pratique

Voici comment un attaquant pourrait exécuter cette attaque avec des outils courants :

Avec jwt_tool

# Extraire la clé publique depuis l'endpoint JWKS
curl https://cible.com/.well-known/jwks.json  jwks.json

# Créer un token falsifié
python jwt_tool.py token_original.txt -X k -pk public_key.pem

Implémentation Python manuelle

import jwt
import base64

# Lire la clé publique
with open('public_key.pem', 'r') as f:
    public_key = f.read()

# Créer une charge malveillante
payload = {
    'sub': 'user123',
    'role': 'admin',
    'iat': 1234567890
}

# Signer avec HS256 en utilisant la clé publique comme secret
forged_token = jwt.encode(
    payload,
    public_key,
    algorithm='HS256'
)

print(forged_token)

Avec Burp Suite

Une fois que vous avez la clé publique dans un format adéquat, vous pouvez modifier le JWT à votre guise, en vous assurant que l’en-tête alg est réglé sur HS256, puis signer le token avec HS256 en utilisant la clé RSA publique comme secret.

Techniques avancées d’exploitation

Récupération de la clé publique

Dans les cas où la clé publique n’est pas facilement accessible, vous pouvez toujours tester la confusion d’algorithme en dérivant la clé à partir d’une paire de JWT existants avec des outils comme jwt_forgery.py.

La relation mathématique entre plusieurs signatures créées avec la même clé privée peut être exploitée pour reconstruire la clé publique, nécessitant seulement deux JWT signés avec la même clé.

Sensibilité au format

La clé publique utilisée pour signer doit être absolument identique à celle stockée sur le serveur, y compris le format et la conservation des caractères non imprimables comme les sauts de ligne. Les attaquants doivent souvent expérimenter avec différents formats de clé :

  • Format PEM avec en-têtes
  • Matériel de clé brut
  • Styles de fin de ligne différents (CRLF vs LF)
  • Avec ou sans sauts de ligne finaux

Détection et tests

Identifier les applications vulnérables

Les chercheurs en sécurité peuvent tester la confusion d’algorithme en :

  1. Analyser les en-têtes JWT pour identifier l’algorithme utilisé
  2. Localiser les clés publiques via les endpoints JWKS ou autres
  3. Tenter l’attaque en modifiant l’algorithme et en signant avec la clé publique
  4. Observer le comportement du serveur pour voir si le token falsifié est accepté

Analyse automatique

Depuis Burp Suite Professional 2022.5.1, Burp Scanner peut détecter automatiquement plusieurs vulnérabilités dans les mécanismes JWT, y compris les attaques de confusion d’algorithme.

Stratégies de défense : protéger vos applications

1. Spécifier explicitement les algorithmes attendus

Les bibliothèques JWT doivent ajouter un paramètre d’algorithme à leur fonction de vérification, et le serveur doit connaître à l’avance l’algorithme utilisé pour signer.

Mise en œuvre sécurisée :

// Node.js avec jsonwebtoken
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
# Python avec PyJWT
jwt.decode(token, public_key, algorithms=['RS256'])
// Java avec jjwt
Jwts.parserBuilder()
    .setSigningKey(publicKey)
    .requireAlgorithm(SignatureAlgorithm.RS256)
    .build()
    .parseClaimsJws(token);

2. Utiliser une liste blanche d’algorithmes

Il est préférable d’adopter une liste blanche, en définissant explicitement les algorithmes autorisés comme HS256 ou RS256, ce qui garantit un contrôle strict et évite les failles dues à des interprétations laxistes.

3. Séparer la logique de vérification selon le type de clé

Ne jamais utiliser la même méthode de vérification pour des clés symétriques et asymétriques. Implémentez des chemins de code séparés :

function verifyToken(token, expectedAlgorithm, key) {
    // Extraire l'algorithme de l'en-tête pour journalisation
    const header = JSON.parse(
        Buffer.from(token.split('.')[0], 'base64').toString()
    );
    
    // NE JAMAIS faire confiance à l'algorithme de l'en-tête
    // Toujours utiliser l'algorithme attendu
    if (expectedAlgorithm === 'RS256') {
        return verifyRS256(token, key);
    } else if (expectedAlgorithm === 'HS256') {
        return verifyHS256(token, key);
    }
    
    throw new Error('Algorithme non supporté');
}

4. Vérification de type

Certaines bibliothèques incluent désormais des protections pour détecter l’utilisation d’une clé publique là où un secret symétrique est attendu :

function isPublicKey(key) {
    return key.includes('BEGIN PUBLIC KEY') || 
           key.includes('BEGIN RSA PUBLIC KEY');
}

function verifyHS256(token, secret) {
    if (isPublicKey(secret)) {
        throw new Error('Une clé publique ne peut pas être utilisée comme secret HMAC');
    }
    return jwt.verify(token, secret, { algorithms: ['HS256'] });
}

5. Rejeter l’algorithme “none”

L’algorithme none est destiné à être utilisé lorsque l’intégrité du token a déjà été vérifiée, mais malheureusement certaines bibliothèques traitent les tokens signés avec none comme valides.

Toujours rejeter explicitement les tokens utilisant l’algorithme “none” en production :

const decoded = jwt.verify(token, key, {
    algorithms: ['RS256', 'HS256'],
    // L'algorithme 'none' est automatiquement rejeté
});

6. Utiliser des secrets forts pour HMAC

Lors de l’implémentation JWT, les développeurs font parfois l’erreur d’oublier de changer les secrets par défaut ou de remplacement, ce qui facilite la tâche d’un attaquant pour brute-forcer le secret du serveur avec une liste de secrets connus.

Pour HS256 : - Utiliser des secrets cryptographiquement aléatoires d’au moins 256 bits - Stocker les secrets en toute sécurité dans des variables d’environnement ou des systèmes de gestion de secrets - Faire tourner les secrets régulièrement - Ne jamais coder en dur les secrets dans le code source

7. Valider tous les claims en profondeur

Au-delà de la validation de l’algorithme, implémentez une validation complète des claims :

jwt.verify(token, publicKey, {
    algorithms: ['RS256'],
    issuer: 'https://trusted-issuer.com',
    audience: 'votre-application',
    clockTolerance: 60 // secondes de marge pour les comparaisons temporelles
});

8. Maintenir les bibliothèques à jour

Pour corriger CVE-2024-37568, il est impératif de mettre à jour Authlib à la version 1.3.1 ou ultérieure, qui inclut des correctifs robustes pour prévenir la confusion d’algorithme et assurer une validation JWT correcte.

Mettre régulièrement à jour les bibliothèques JWT pour bénéficier des correctifs de sécurité et d’une meilleure validation.

Bonnes pratiques pour la sécurité JWT

Liste de vérification de sécurité complète

Gestion des algorithmes : - ✅ Spécifier explicitement les algorithmes autorisés dans les appels de vérification - ✅ Ne jamais faire confiance à l’algorithme du header du token - ✅ Rejeter explicitement l’algorithme “none” en production - ✅ Utiliser des algorithmes asymétriques (RS256, ES256) dans la majorité des cas - ✅ Mettre en place une liste blanche d’algorithmes au niveau de l’application

Gestion des clés : - ✅ Stocker les clés privées en toute sécurité avec des services de gestion de clés - ✅ Utiliser des secrets forts, générés aléatoirement, pour HMAC - ✅ Faire tourner les clés régulièrement avec des périodes de grâce - ✅ Rendre les clés publiques accessibles tout en protégeant les clés privées - ✅ Ne jamais intégrer les clés dans le code source ou les fichiers de configuration

Gestion des tokens : - ✅ Définir des durées d’expiration courtes (15 minutes ou moins pour les tokens d’accès) - ✅ Implémenter la rotation des refresh tokens - ✅ Valider tous les claims standards (iss, aud, exp, nbf, iat) - ✅ Utiliser exclusivement HTTPS pour la transmission des tokens - ✅ Stocker les tokens en toute sécurité (cookies HttpOnly pour les applications web)

Mise en œuvre : - ✅ Utiliser des bibliothèques JWT bien maintenues et à jour - ✅ Gérer correctement les erreurs sans divulguer d’informations - ✅ Journaliser les événements de sécurité pour la surveillance et la réponse aux incidents - ✅ Effectuer des audits de sécurité réguliers et des tests de pénétration - ✅ Sensibiliser les développeurs aux principes de sécurité JWT

Choisir le bon algorithme

Pour les nouvelles applications : - RS256 ou ES256 : Idéal pour la majorité des scénarios nécessitant une distribution de clés publiques - PS256 : Sécurité renforcée par rapport à RS256 avec des signatures probabilistes - EdDSA : Très sécurisé et efficace, idéal pour les nouvelles implémentations

À éviter : - HS256 pour les API publiques où le secret pourrait être exposé - Clés faibles : minimum 2048 bits pour RSA, 256 bits pour ECDSA - Flexibilité d’algorithme : Ne pas supporter plusieurs algorithmes sauf si absolument nécessaire

Tester votre implémentation

Étapes d’évaluation des vulnérabilités

  1. Revoir le code de vérification pour s’assurer que les algorithmes sont explicitement spécifiés
  2. Tester avec des tokens modifiés où l’algorithme est changé
  3. Tenter la substitution de clé publique pour vérifier la protection
  4. Vérifier l’acceptation de l’algorithme “none” dans tous les environnements
  5. Vérifier la sensibilité au format de la clé pour ne pas compromettre la sécurité

Outils de sécurité

  • jwt_tool : Outil complet de test JWT
  • Burp Suite : Test de sécurité des applications web avec extensions JWT
  • OWASP ZAP : Scanner de sécurité open-source avec support JWT
  • Scripts personnalisés : Scripts Python ou Node.js pour des tests spécifiques

Contexte plus large : paysage de la sécurité JWT

La confusion d’algorithme n’est qu’une des vulnérabilités JWT que les applications doivent défendre :

  • Secrets faibles : force brute sur les secrets HMAC
  • Vérification de signature manquante : acceptation de tokens non signés
  • Fuite de tokens : exposition via logs, URLs ou stockage côté client
  • Rejeu : réutilisation de tokens capturés
  • Injection JKU/X5U : manipulation de paramètres d’en-tête
  • Injection Kid : traversée de chemin via l’identifiant de clé

Les JWT ne sont pas sécurisés simplement parce qu’ils sont JWT ; c’est leur utilisation qui détermine leur sécurité.

Conclusion : la vigilance est essentielle

La confusion d’algorithme JWT représente une vulnérabilité critique qui a affecté de nombreuses bibliothèques majeures et continue d’apparaître dans de nouvelles implémentations. L’attaque exploite une faille fondamentale de confiance : laisser des tokens non vérifiés dicter la façon dont ils doivent être vérifiés.

Ne faites jamais confiance au champ “alg” du JWT lui-même, et imposez l’algorithme attendu au niveau de la configuration. En mettant en œuvre une validation explicite de l’algorithme, en utilisant des méthodes de vérification spécifiques à l’algorithme, et en suivant les meilleures pratiques de sécurité, les développeurs peuvent protéger leurs applications contre cette voie d’attaque dévastatrice.

Le message clé : Ne faites jamais confiance aux entrées utilisateur, surtout lorsqu’elles déterminent des opérations critiques en matière de sécurité. Le champ alg dans l’en-tête JWT est une donnée contrôlée par l’utilisateur, provenant d’une source non vérifiée. Traitez-la avec le même scepticisme que toute autre donnée non fiable, et appliquez toujours votre politique de sécurité de manière explicite dans le code.

À mesure que les mécanismes d’authentification évoluent, rester informé des vulnérabilités comme la confusion d’algorithme et mettre en œuvre une stratégie de défense en profondeur est essentiel pour maintenir la sécurité des applications. Des audits réguliers, la formation des développeurs, et une surveillance proactive sont les piliers d’une posture de sécurité JWT robuste.


Ressources pour approfondir :

  • OWASP JWT Security Cheat Sheet
  • RFC 7519 : JSON Web Token (JWT)
  • RFC 8725 : Bonnes pratiques actuelles pour JWT
  • PortSwigger Web Security Academy : Attaques JWT
  • Outils de test JWT de Burp Suite

Restez sécurisé, vérifiez explicitement, et ne faites jamais confiance à l’en-tête alg ! 🔒

Continue from this article into the most relevant product guides and workflows.

Related Topics

#JWT algorithm confusion, JWT vulnerability, RS256 to HS256 attack, JWT token forgery, JSON Web Token exploit, JWT signature bypass, JWT security, JWT misconfiguration, JWT hacking, JWT validation flaw, JWT RS256 vulnerability, JWT HS256 exploit, JWT header tampering, JWT signature confusion, JWT public key attack, JWT asymmetric to symmetric, JWT authentication bypass, JWT algorithm spoofing, JWT attack 2025, JWT cryptography flaw, JWT pen testing, JWT bug bounty, JWT algorithm confusion example, JWT security misconfiguration, RS256 vs HS256, JWT verification flaw, JWT exploit tutorial, JWT manipulation, JWT injection, JWT cracking, JWT signature validation, JWT best practices, JWT secure implementation, JWT token validation, JWT algorithm confusion prevention, JWT library vulnerability, JWT attack detection, JWT forge token, JWT public key secret, JWT exploit chain, JWT hack demo, JWT algorithm confusion CVE, JWT exploit research, JWT misused algorithms, JWT bypass authentication, JWT implementation flaws, JWT pentesting techniques, JWT header attack, JWT payload tampering, RS256 public key secret, HS256 confusion exploit, JWT asymmetric signature vulnerability, JWT algorithm downgrade, JWT secure verification, JWT exploit mitigation

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles