Skip to content
Back to Blog
jwtsecurityvulnerabilityauthentication

Attaques JWT : algorithme none et confusion RS256/HS256

Deux attaques JWT classiques, alg:none et confusion RS256→HS256, exploitent les serveurs qui font confiance à l'en-tête alg. Explications pas à pas et correctif en une ligne.

SZ
Founder, Molixa
11 min read
Partager
Attaques JWT : algorithme none et confusion RS256/HS256
Table of contents6 sections

La vulnérabilité de l'algorithme jwt none permet à un attaquant de supprimer la signature d'un jeton et de réécrire son contenu, et le serveur accepte le jeton falsifié comme valide. Cela se produit lorsque votre code fait confiance au champ alg dans l'en-tête du jeton au lieu de décider vous-même de l'algorithme. La même cause racine alimente l'attaque de confusion RS256-vers-HS256. Les deux sont des contournements d'authentification, et les deux se ferment avec une ligne de code.

Si vous utilisez des JSON Web Tokens, c'est l'un des rares bugs de sécurité qui transforme une nuisance en lecture seule en une prise de contrôle totale du compte. Un attaquant capable de forger un jeton valide peut définir "sub": "admin", ne rien signer, et entrer. Ci-dessous, vous verrez exactement comment chaque attaque fonctionne, avec les octets détaillés, ainsi que le correctif par liste blanche qui met fin à toute cette classe de bug.

Ce qu'est réellement la vulnérabilité de l'algorithme JWT None#

Un JWT se compose de trois parties séparées par des points : un en-tête en base64url, un payload en base64url et une signature. L'en-tête déclare l'algorithme qui a signé le jeton, par exemple {"alg":"HS256","typ":"JWT"}. La signature prouve que le jeton n'a pas été modifié.

L'algorithme none fait partie intégrante de la spécification JWT (RFC 7519). Il signifie que le jeton n'est pas signé. Il existe pour les cas où la couche de transport garantit déjà l'intégrité, la signature est donc intentionnellement vide. Le problème n'est pas que none existe. Le problème survient lorsqu'une bibliothèque de vérification traite l'en-tête alg: none d'un jeton comme une autorisation à ignorer complètement la vérification de la signature.

Le défaut central des deux attaques ci-dessous est identique : le serveur lit l'en-tête alg contrôlé par l'attaquant et lui fait confiance pour décider comment (ou si) vérifier la signature. Ne laissez jamais une entrée non fiable choisir votre algorithme de vérification.

La contrefaçon en trois étapes#

Voici l'attaque contre un serveur qui honore alg: none. Supposons qu'un vrai jeton se décode en ce payload :

{ "sub": "1234", "role": "user", "exp": 1735689600 }

Un attaquant fait trois choses :

  1. Modifie l'en-tête en {"alg":"none","typ":"JWT"} et l'encode en base64url.
  2. Modifie le payload en {"sub":"1","role":"admin","exp":9999999999} et l'encode.
  3. Supprime la signature, laissant le jeton se terminer par un point final sans rien après.

Le jeton falsifié ressemble à eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxIiwicm9sZSI6ImFkbWluIn0. (notez le point suspendu). Un serveur vulnérable décode l'en-tête, voit none, ignore la vérification et accorde les droits admin. Pas de secret, pas de clé, pas de craquage. Vous pouvez coller n'importe quel jeton dans notre décodeur JWT gratuit pour voir exactement quel en-tête alg il porte avant de lui faire confiance.

Pourquoi "none" a parfois un N majuscule#

Certaines bibliothèques anciennes bloquaient la chaîne none en respectant la casse, mais pas None, NONE ou nOnE. Comme la spécification JWT traite les noms d'algorithmes en respectant la casse, mais que le code réel ne le faisait pas toujours, les attaquants contournaient les listes noires naïves en variant la casse. C'est la première leçon de sécurité JWT : une liste noire de mauvaises valeurs est fragile. Une liste blanche de bonnes valeurs ne l'est pas.

L'attaque par confusion d'algorithme RS256 vers HS256#

L'attaque par confusion est plus sournoise et piège encore des équipes en 2026. Elle exploite la différence entre le chiffrement symétrique et asymétrique lorsqu'un seul appel de vérification accepte les deux.

Deux familles d'algorithmes sont concernées :

  • HS256 est symétrique. Une seule clé secrète signe et vérifie. Celui qui détient la clé peut créer des jetons valides.
  • RS256 est asymétrique. Une clé privée signe, et une clé publique vérifie. La clé publique est, par conception, publique. Il est normal de la publier.

Un serveur utilisant RS256 garde sa clé privée verrouillée et vérifie les jetons entrants avec la clé publique. C'est sûr, tant que le serveur n'exécute que la vérification RS256.

Comment la clé publique devient un secret de falsification#

La confusion se produit lorsque le code de vérification ressemble à ceci :

// VULNÉRABLE : l'algorithme est extrait de l'en-tête du jeton
jwt.verify(token, key);

De nombreuses bibliothèques, lorsqu'elles reçoivent un jeton, lisent l'en-tête alg pour choisir le chemin de vérification. Si le système d'origine est RS256, l'attaquant fait ceci :

  1. Obtient la clé publique RSA. Elle est souvent exposée sur un point de terminaison JWKS, dans une URL .well-known, dans un SDK, ou simplement publiée dans la documentation.
  2. Crée un jeton avec l'en-tête modifié en {"alg":"HS256"} et une charge utile élevée.
  3. Signe ce jeton avec HMAC-SHA256, en utilisant les octets exacts de la clé publique comme secret HMAC.

Maintenant, le serveur reçoit un jeton HS256. Il extrait sa clé RSA (qu'il croyait n'être qu'une clé de vérification) et exécute HMAC avec celle-ci. Comme l'attaquant a signé avec la même chaîne de clé publique, le HMAC correspond. La signature est vérifiée. Le jeton administrateur falsifié est accepté.

L'attaquant a transformé votre clé publique inoffensive et publiée en secret qui falsifie les jetons. Il n'a jamais eu besoin de la clé privée.

Attention : la partie la plus délicate pour reproduire ceci est d'obtenir la représentation exacte en octets de la clé publique (PEM avec le saut de ligne final, en-têtes inclus ou supprimés). Les attaquants testent par force brute le petit nombre d'encodages courants. Considérez tout déploiement RS256 qui accepte également HS256 comme déjà compromis.

Pourquoi cela est si facile à introduire par accident#

La vulnérabilité n'est presque jamais écrite intentionnellement. Elle s'infiltre lorsque :

  • Une bibliothèque déduit par défaut l'algorithme de l'en-tête du jeton.
  • Une équipe migre de HS256 vers RS256 mais laisse l'ancien chemin de vérification activé "au cas où."
  • Une fonction d'encapsulation accepte un argument key générique et le transmet à l'algorithme demandé par le jeton.

Si vous voulez comprendre pourquoi décoder un jeton n'est pas la même chose que le vérifier, l'analyse dans décoder versus vérifier dans la sécurité JWT montre où les équipes confondent les deux et ouvrent exactement cette faille.

La solution : autoriser explicitement votre algorithme#

Les deux attaques échouent dès que le serveur cesse de se fier à l'en-tête alg du jeton et impose l'algorithme qu'il accepte. C'est la défense JWT la plus importante, et elle tient généralement en une ligne.

Définir l'algorithme explicitement#

Avec Node et la bibliothèque courante jsonwebtoken, passez une liste d'autorisation explicite algorithms :

// SÉCURISÉ : seul HS256 est accepté
jwt.verify(token, secret, { algorithms: ["HS256"] });

// SÉCURISÉ : seul RS256, avec la clé PUBLIQUE, rien d'autre
jwt.verify(token, publicKey, { algorithms: ["RS256"] });

Avec cette liste d'autorisation, un jeton falsifié avec alg: none est rejeté car none n'est pas dans la liste. Un jeton HS256 falsifié envoyé au vérificateur RS256 est rejeté car le vérificateur n'exécutera que RS256, et des octets HMAC ne peuvent pas satisfaire une vérification de signature RSA.

Toutes les bibliothèques JWT matures offrent le même contrôle sous un nom légèrement différent :

Langage / BibliothèqueParamètre de liste d'autorisation
Node jsonwebtokenalgorithms: ["RS256"] dans verify()
Python PyJWTalgorithms=["RS256"] dans jwt.decode()
Go golang-jwtWithValidMethods([]string{"RS256"})
Java java-jwt (Auth0)construire le vérificateur avec l'Algorithm spécifique
PHP firebase/php-jwtpasser l'algorithme à JWT::decode()

Une courte liste de vérification pour renforcer la sécurité#

Définir l'algorithme est la correction principale. Ces habitudes comblent le reste des lacunes :

  • N'acceptez jamais none en production. Il n'y a aucune raison pour qu'un jeton d'utilisateur connecté ne soit pas signé.
  • Utilisez un seul algorithme par service. Si vous n'avez pas besoin à la fois de HS256 et RS256, ne laissez pas votre vérificateur accepter les deux. Les mélanger est ce qui invite à l'attaque par confusion.
  • Gardez les clés de vérification typées. Chargez votre clé publique RSA en tant qu'objet clé, pas une chaîne brute, afin qu'elle ne puisse pas être accidentellement utilisée comme secret HMAC.
  • Validez les revendications, pas seulement la signature. Vérifiez exp, iss et aud. Une signature valide sur un jeton destiné à un autre service reste un problème.
  • Inspectez les jetons que vous recevez. Avant d'intégrer un jeton tiers, décodez-le et confirmez que l'en-tête et les revendications correspondent à ce que vous attendez.

Vous pouvez vérifier tout cela sur un vrai jeton en quelques secondes. Notre décodeur JWT et outil de sécurité affiche l'en-tête, la charge utile et l'algorithme déclaré par le jeton, afin que vous puissiez repérer un alg: none ou un HS256 inattendu avant qu'il n'atteigne votre vérificateur. Le guide complémentaire sur la lecture des résultats du décodeur JWT pour la sécurité des jetons explique ce que chaque champ vous indique.

Comment savoir si votre application est vulnérable#

Vous n'avez pas besoin d'une équipe de pentest pour le découvrir. Trois vérifications rapides couvrent la plupart des risques réels.

Vérification 1 : L'algorithme est-il verrouillé ?#

Parcourez votre codebase pour chaque appel qui vérifie un jeton. Si un chemin de vérification omet une liste blanche d'algorithms (ou son équivalent), ce chemin fait confiance à l'en-tête du jeton et est suspect. C'est la vérification la plus importante, et elle prend quelques minutes.

Vérification 2 : Un jeton "none" passe-t-il ?#

Prenez un jeton valide, modifiez son en-tête en {"alg":"none","typ":"JWT"}, modifiez une revendication, supprimez la signature (conservez le point final) et envoyez-le à un point de terminaison protégé. Une réponse 200 avec l'identité falsifiée confirme la vulnérabilité. Une réponse 401 confirme que le chemin la rejette.

Vérification 3 : Votre clé publique est-elle vraiment publique, et quelque chose accepte-t-il HS256 ?#

Si vous signez avec RS256, supposez que la clé publique est entre les mains d'un attaquant. La seule chose qui vous sépare d'un jeton falsifié est de savoir si un vérificateur dans votre pile exécute HS256. Si la réponse est oui quelque part, vous êtes exposé à l'attaque par confusion jusqu'à ce que vous verrouilliez RS256.

Foire aux questions#

La vulnérabilité de l'algorithme JWT none est-elle toujours pertinente en 2026 ? Oui. Les bibliothèques modernes et maintenues rejettent alg: none par défaut et exigent une liste blanche explicite, donc une installation récente est généralement sûre. Le bogue persiste dans les anciennes versions de bibliothèques, dans le code JWT fait maison et dans les applications qui remplacent les valeurs par défaut pour « favoriser la flexibilité ». Auditer vos appels de vérification reste utile.

Pourquoi publier ma clé publique RS256 est-il sûr si elle peut forger des jetons ? La clé publique seule est inoffensive. Elle ne devient dangereuse que lorsque votre serveur accepte la vérification HS256 et traite cette clé publique comme un secret HMAC. Corrigez l'acceptation de HS256 (fixez RS256), et publier la clé publique est exactement aussi sûr que prévu par la conception.

Que signifie « mettre l'algorithme sur liste blanche » en pratique ? Cela signifie indiquer à votre fonction de vérification l'algorithme ou les algorithmes exacts que vous acceptez, plutôt que de la laisser lire l'algorithme depuis le jeton entrant. Dans jsonwebtoken, cela donne verify(token, key, { algorithms: ["RS256"] }). Le vérificateur ignore alors l'en-tête alg du jeton pour décider comment vérifier la signature.

Puis-je simplement bloquer la chaîne « none » pour rester en sécurité ? Non. Les listes noires sont fragiles. Les attaquants contournent les blocages sensibles à la casse avec None ou NONE, et une liste noire ne protège pas contre l'attaque de confusion RS256-vers-HS256, qui utilise une valeur HS256 parfaitement normale. Une liste blanche d'algorithmes acceptés défend contre les deux attaques à la fois.

Comment inspecter l'algorithme utilisé par un jeton ? Décodez le premier segment du jeton, qui est l'en-tête encodé en base64url contenant le champ alg. Vous pouvez le faire manuellement ou coller le jeton dans un décodeur JWT qui affiche l'en-tête, la charge utile et l'algorithme déclaré. Le décodage ne valide jamais la signature, donc traitez le résultat comme informatif jusqu'à ce que votre serveur le vérifie avec un algorithme fixé.

Utiliser un secret plus long ou une clé plus forte résout-il ce problème ? Non. Une clé RSA de 4 096 bits n'aide pas si le vérificateur peut être trompé en mode HMAC, et un secret HMAC fort n'aide pas si le serveur accepte des jetons non signés none. Ces attaques contournent la cryptographie plutôt que de la briser, donc le remède est de fixer l'algorithme, pas d'augmenter la force de la clé.

Le verdict sur la vulnérabilité de l'algorithme JWT None#

La vulnérabilité de l'algorithme JWT None et l'attaque par confusion RS256-vers-HS256 partagent une cause racine commune : faire confiance aux entrées contrôlées par l'attaquant pour décider comment un jeton est vérifié. Supprimez une signature ou échangez une clé publique en tant que secret HMAC, et un serveur qui suit ses instructions depuis l'en-tête alg acceptera la contrefaçon.

Fixez l'algorithme avec une liste d'autorisation explicite, refusez none en production, et gardez un seul algorithme par service. Cette poignée d'habitudes élimine toute la classe de bugs. Lorsque vous devez confirmer ce que contient réellement un jeton, décodez-le d'abord et vérifiez-le ensuite avec un algorithme fixe, et vous fermez définitivement la porte.

jwtsecurityvulnerabilityauthentication

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools