JWTs Ne Sont Pas Chiffrés : La #1 Faute de Compréhension Qui Mène à des Fuites de Données

Lorsque les développeurs découvrent pour la première fois JSON Web Tokens (JWTs), ils font souvent une hypothèse dangereuse : le token ressemble à du charabia chiffré, donc les données à l’intérieur doivent être sécurisées. Cette erreur a conduit à d’innombrables violations de données, à l’exposition d’informations personnelles identifiables (PII), et à de graves vulnérabilités de sécurité dans des applications à travers le monde. La vérité désagréable est que les JWTs standards sont aussi sécurisés que d’écrire des informations sensibles sur une carte postale et de l’envoyer par la poste — quiconque l’intercepte peut tout lire.
La Mauvaise Compréhension Fondamentale
Les JSON Web Tokens sont devenus la norme de facto pour l’authentification dans les applications web modernes. Ils sont compacts, autonomes, et peuvent transporter des informations sur les utilisateurs et permissions. Cependant, les fonctionnalités qui rendent les JWTs pratiques les font aussi souvent mal compris. La principale erreur vient de leur apparence : une longue chaîne de caractères apparemment aléatoires séparés par des points. Cette apparence crée une fausse sensation de sécurité qui pousse les développeurs à stocker des données sensibles directement dans la charge utile du token.
La réalité est bien moins sécurisée que ce que la plupart des développeurs pensent. Un JWT standard se compose de trois parties séparées par des points : l’en-tête, la charge utile, et la signature. Bien que la signature assure l’intégrité via une signature cryptographique, l’en-tête et la payload sont simplement encodés en Base64URL — pas chiffrés. L’encodage Base64 est une transformation réversible conçue pour représenter des données binaires en format chaîne ASCII, pas une méthode de sécurité. Quiconque possède des connaissances de programmation de base peut décoder un JWT en quelques secondes.
Comprendre la Encodage Base64 vs. Chiffrement
Pour saisir pourquoi cela importe, il faut distinguer encodage et chiffrement. L’encodage Base64 est une transformation simple et réversible qui convertit des données en un ensemble de caractères spécifique. Il est conçu pour la transmission et le stockage, pas pour la sécurité. Toutes les langages de programmation incluent des fonctions intégrées pour encoder et décoder en Base64 en une seule ligne de code. Aucun mot de passe, clé ou secret n’est nécessaire pour inverser le processus.
Le chiffrement, en revanche, est un processus cryptographique qui transforme les données à l’aide d’une clé secrète, rendant leur lecture impossible sans cette clé. Un vrai chiffrement garantit la confidentialité — même si quelqu’un intercepte des données chiffrées, il ne pourra pas les lire sans la clé de déchiffrement. Les JWTs signés avec des algorithmes comme HS256 ou RS256 ne sont pas chiffrés. Ils sont signés, ce qui est fondamentalement différent.
La signature dans un JWT a une seule fonction : vérifier que le token n’a pas été modifié et qu’il a été émis par une source fiable. Lorsqu’un serveur crée un JWT, il génère une signature en hachant l’en-tête encodé et la charge utile avec une clé secrète. Lorsqu’il reçoit le token, il recalcule cette signature pour vérifier l’authenticité. Cependant, cette signature ne sert à rien pour cacher le contenu de la payload. N’importe qui peut lire la payload ; il ne peut simplement pas la modifier sans invalider la signature.
À Quelle Facilité Peut-On Déchiffrer un JWT ?
De façon alarmante, très facilement. Voici une démonstration avec un JWT typique que vous pourriez rencontrer dans une application web :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSIsInNzbiI6IjEyMy00NS02Nzg5Iiwic2FsYXJ5Ijo4NTAwMCwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Pour le décoder, vous n’avez pas besoin d’outils spécialisés ou de compétences en hacking. Vous pouvez visiter jwt.io, un site populaire de débogage JWT, coller le token, et voir instantanément son contenu. Alternativement, vous pouvez écrire un script simple dans n’importe quel langage de programmation. En JavaScript, c’est littéralement une ligne :
JSON.parse(atob(token.split('.')[1]))
En Python, c’est tout aussi simple :
import base64, json
json.loads(base64.b64decode(token.split('.')[1] + '=='))
La charge utile décodée de notre exemple révélerait :
{
"userId": "1234567890",
"email": "john.doe@example.com",
"ssn": "123-45-6789",
"salary": 85000,
"iat": 1516239022
}
Cet exemple illustre une faille de sécurité catastrophique. Le token contient un numéro de sécurité sociale, des informations salariales, et d’autres données personnelles qui ne devraient jamais être transmises en clair. Pourtant, ce scénario se produit plus souvent qu’on ne le voudrait dans les systèmes en production.
Impact Réel : Fuites de Données via une Mauvaise Utilisation des JWT
Les conséquences de traiter les JWT comme des conteneurs chiffrés ne sont pas théoriques. Des chercheurs en sécurité et des testeurs d’intrusion découvrent régulièrement des applications qui fuient des données sensibles via les payloads JWT. Voici quelques exemples courants :
Applications de santé stockant des numéros de dossiers médicaux, codes de diagnostic ou informations d’assurance dans les JWT. Un acteur malveillant interceptant ces tokens pourrait accéder à des informations de santé protégées sans jamais pénétrer la base de données.
Plateformes de services financiers incluant soldes de comptes, historiques de transactions, ou identifiants internes d’utilisateurs liés à des numéros de compte. Ces tokens, capturés via interception réseau ou accès JavaScript côté client, exposent directement des données financières.
Sites e-commerce intégrant les quatre derniers chiffres de la carte de crédit, adresses de livraison, ou historiques d’achats dans les tokens. Bien que les développeurs pensent que des numéros partiels sont sûrs, combinés avec d’autres informations divulguées, ils contribuent au vol d’identité.
Applications d’entreprise internes plaçant des identifiants employés, des plages salariales, des évaluations de performance ou la hiérarchie organisationnelle dans les JWT. Si ces tokens sont exposés via les outils de développement du navigateur ou les logs réseau, ils peuvent révéler des informations confidentielles.
Des vulnérabilités récentes en 2025, comme CVE-2025-2079 et CVE-2025-20188, impliquaient des secrets JWT codés en dur permettant aux attaquants de générer des tokens valides, mais le problème fondamental dépasse la gestion des secrets. Même avec des secrets de signature bien sécurisés, la nature lisible des payloads JWT présente un risque inhérent lorsque les développeurs stockent des informations sensibles à l’intérieur.
L’Anatomie d’un JWT : Qu’est-ce Qui Est Vraiment Protégé ?
Un JWT se compose de trois composants, chacun ayant un but précis :
L’En-tête (encodé en Base64URL) spécifie le type de token et l’algorithme de signature utilisé. Il ressemble généralement à :
{
"alg": "HS256",
"typ": "JWT"
}
La Charge Utile (encodée en Base64URL) contient les claims — déclarations sur une entité et des données supplémentaires. C’est ici que les développeurs font souvent des erreurs critiques, stockant des informations sensibles qu’ils pensent protégées.
La Signature (générée cryptographiquement) vérifie l’intégrité du token. Pour HS256, elle est créée en hachant l’en-tête et la charge utile encodés avec une clé secrète via HMAC-SHA256.
Seule la signature offre une propriété de sécurité, et cette propriété est l’intégrité, pas la confidentialité. La signature prouve que le token n’a pas été modifié et qu’il a été émis par quelqu’un possédant la clé secrète. Elle ne cache pas le contenu de la payload.
Que Devrait Contenir un JWT ?
Si les données sensibles ne doivent jamais apparaître dans la payload du JWT, que devrait-il y avoir ? La réponse est des identifiants non sensibles et des métadonnées qui aident le serveur à valider les requêtes et à maintenir une authentification sans état.
Contenu approprié pour la payload du JWT :
- Identifiant utilisateur ou nom d’utilisateur (identifiants non sensibles)
- Temps d’expiration du token (claim exp)
- Horodatage d’émission (claim iat)
- Identification de l’émetteur (claim iss)
- Identification du sujet (claim sub)
- Spécification de l’audience (claim aud)
- Rôles ou permissions non sensibles
- Identifiants de session
Le principe clé est que tout dans la payload doit être une information que vous seriez à l’aise de voir dans des logs d’application ou la console du serveur. Si vous ne voudriez pas que ces données apparaissent dans un fichier de logs que d’autres pourraient lire, elles ne devraient pas être dans la payload du JWT.
Pour les informations sensibles, maintenez un stockage côté serveur avec le JWT contenant uniquement un identifiant de référence. Lorsqu’il reçoit le token, le serveur extrait l’identifiant utilisateur ou de session, puis consulte une base de données sécurisée pour récupérer les informations supplémentaires. Cette approche maintient les avantages de l’authentification sans état tout en protégeant les données sensibles.
L’Alternative : Les Tokens Opaces pour la Gestion de Session
De nombreux experts en sécurité soutiennent que pour la gestion de session, les tokens opaques offrent de meilleures caractéristiques de sécurité que les JWTs. Un token opaque est une chaîne générée aléatoirement qui sert de clé de recherche pour les données de session côté serveur. Contrairement aux JWTs, les tokens opaques ne révèlent rien sur l’utilisateur ou la session — ils sont véritablement sans signification pour quiconque les intercepte.
Lors de l’implémentation de tokens opaques, le serveur génère une chaîne aléatoire cryptographiquement, l’associe aux données de session de l’utilisateur dans un stockage sécurisé (comme Redis ou une base de données), et renvoie le token au client. Lors des requêtes suivantes, le client envoie le token, et le serveur recherche les données de session associées. Si le token n’existe pas dans le stockage ou a expiré, la requête est rejetée.
Cette approche offre plusieurs avantages de sécurité. Premièrement, le contenu du token n’est jamais exposé car il n’y a pas de contenu — seulement un identifiant aléatoire. Deuxièmement, les sessions peuvent être immédiatement révoquées en supprimant l’enregistrement côté serveur, ce qui est impossible avec des JWTs sans état. Troisièmement, les données sensibles de session ne quittent jamais l’environnement serveur.
L’inconvénient est une augmentation des besoins en stockage côté serveur et des recherches dans la base de données à chaque requête. Pour de nombreuses applications, surtout celles manipulant des données sensibles, cet échange en vaut la peine. Les bénéfices en sécurité surpassent le léger surcoût en performance.
Quand Utiliser les JWT ?
Malgré ces préoccupations, les JWT ont des cas d’usage légitimes où ils apportent de véritables avantages. Ils excellent dans les scénarios nécessitant une authentification sans état à travers des systèmes distribués, comme les architectures microservices où le stockage centralisé de session créerait des goulots d’étranglement.
Les JWT fonctionnent bien pour l’authentification API où le token ne transporte que des identifiants non sensibles et où la passerelle API peut vérifier les signatures sans requête à la base de données. Ils sont utiles pour les systèmes d’authentification unique (SSO) où plusieurs applications font confiance au même émetteur et doivent vérifier l’authentification utilisateur de manière indépendante. Ils conviennent pour les tokens d’accès à courte durée dans les flux OAuth 2.0 où les temps d’expiration sont mesurés en minutes et où des opérations sensibles nécessitent une vérification supplémentaire.
L’essentiel est de comprendre que les JWT offrent l’authentification et la vérification d’intégrité, pas la confidentialité. Lorsqu’ils sont utilisés correctement — avec un contenu minimal dans la payload et des contrôles de sécurité appropriés — ils remplissent leur rôle. Les problèmes surgissent lorsque les développeurs mal interprètent leurs propriétés de sécurité et les traitent comme des conteneurs chiffrés.
JWE : Quand Vous Avez Vraiment Besoin de Chiffrement
Pour les scénarios nécessitant des payloads chiffrés, la spécification JWT inclut un frère moins connu : JSON Web Encryption (JWE). Les tokens JWE sont en réalité chiffrés, offrant la confidentialité pour le contenu de la payload. Contrairement aux JWT standards (techniquement appelés JWS — JSON Web Signature), les tokens JWE ne peuvent pas être décodés sans la clé de chiffrement.
Un token JWE comporte cinq parties au lieu de trois, incluant des en-têtes pour l’algorithme de chiffrement et la gestion des clés, une clé chiffrée, un vecteur d’initialisation, le texte chiffré, et une balise d’authentification. La payload est réellement chiffrée à l’aide d’algorithmes comme AES-GCM, la rendant illisible à quiconque ne possède pas la clé de déchiffrement.
Cependant, JWE introduit une complexité importante. La gestion des clés devient critique — perdre les clés de chiffrement signifie perdre l’accès à tous les tokens chiffrés avec ces clés. La surcharge de performance augmente en raison des opérations de chiffrement et de déchiffrement. Les erreurs d’implémentation dans le code cryptographique peuvent créer des vulnérabilités pires que de stocker des données en clair.
La plupart des applications n’ont pas besoin de JWE. La meilleure approche est généralement de garder les données sensibles hors des tokens, en utilisant un stockage côté serveur avec des identifiants référencés. La JWE doit être réservée à des scénarios spécifiques où les tokens chiffrés offrent des avantages clairs, comme le partage d’authentification entre organisations avec des frontières de confiance différentes.
Bonnes Pratiques pour la Sécurité des JWT
Mettre en œuvre une authentification sécurisée basée sur JWT nécessite de suivre des bonnes pratiques établies pour éviter les vulnérabilités courantes :
Ne jamais stocker de données sensibles dans la payload du JWT. C’est la règle la plus critique. Considérez chaque JWT comme lisible par un attaquant, car statistiquement, beaucoup le seront.
Utiliser des durées d’expiration courtes. Limitez la durée de vie des JWT à quelques minutes ou heures, pas des jours ou des semaines. Des fenêtres d’expiration plus courtes limitent les dégâts en cas de compromission.
Mettre en œuvre des mécanismes de rafraîchissement de token. Émettre des tokens d’accès à courte durée avec des tokens de rafraîchissement plus longs et stockés en toute sécurité. Cela limite l’exposition tout en conservant la commodité.
Valider toutes les claims du JWT. Vérifiez toujours la signature, contrôlez l’expiration, validez l’émetteur, et assurez-vous que l’audience correspond à votre application. Ne faites jamais confiance à un JWT non vérifié.
Utiliser des algorithmes de signature forts. Préférez RS256 (signatures RSA) à HS256 (HMAC) pour une meilleure séparation des clés. Évitez les attaques de confusion d’algorithme en imposant l’algorithme attendu côté serveur, et ne laissez jamais le header du JWT dicter l’algorithme à utiliser.
Stocker les secrets de signature en toute sécurité. Ne jamais coder en dur les secrets dans le code de l’application ou les commettre dans le contrôle de version. Utilisez des variables d’environnement, des services de gestion de clés, ou des solutions de stockage de secrets dédiées.
Utiliser HTTPS correctement. Toujours transmettre les JWT via des connexions chiffrées. L’interception réseau de trafic JWT non chiffré expose les tokens aux attaquants.
Envisager des stratégies de révocation de tokens. Bien que les JWT soient sans état, les applications critiques devraient implémenter une liste noire ou maintenir un état minimal de session pour la révocation.
Former les Équipes de Développement
Peut-être la mesure de sécurité la plus importante est la formation. La mauvaise compréhension des JWT persiste car les développeurs ne connaissent pas la différence entre encodage, signature, et chiffrement. La formation en sécurité doit explicitement combler cette lacune, en montrant à quel point il est facile de décoder un JWT et en soulignant les implications.
Les processus de revue de code doivent signaler toute implémentation JWT stockant des données sensibles dans la payload. Les outils d’analyse statique peuvent être configurés pour détecter les mauvaises pratiques courantes. Les tests de sécurité doivent inclure la vérification du contenu JWT pour des données sensibles exposées.
Les organisations doivent établir des politiques claires sur l’utilisation des JWT, en précisant quelles données doivent y figurer et lesquelles nécessitent un stockage côté serveur. La documentation doit inclure des exemples d’implémentations correctes et incorrectes, avec des explications claires sur les implications de sécurité.
Conclusion
La fausse idée que les JWT offrent un chiffrement a conduit à d’innombrables fuites de données et continue de mettre les systèmes en danger. Comprendre que l’encodage Base64 n’est pas du chiffrement est fondamental pour mettre en place des systèmes d’authentification sécurisés. Les JWT standards offrent une vérification d’intégrité via des signatures, mais n’offrent aucune protection de confidentialité pour le contenu de la payload.
Pour un développement sécurisé, traitez la payload du JWT comme des données lisibles publiquement. Stockez uniquement des identifiants non sensibles dans les tokens, maintenez les informations sensibles côté serveur, et envisagez des tokens opaques pour la gestion de session dans des applications sensibles. Lors de l’implémentation des JWT, suivez les bonnes pratiques, validez toutes les claims, et utilisez des durées d’expiration appropriées.
La sécurité des applications web modernes dépend de la compréhension par les développeurs des outils qu’ils utilisent. Les JWT sont puissants et utiles lorsqu’ils sont appliqués correctement, mais dangereux lorsqu’ils sont mal compris. En reconnaissant que les JWT ne sont pas chiffrés et en concevant les systèmes en conséquence, les développeurs peuvent tirer parti de leurs avantages tout en évitant les fuites de données qui leur ont valu une mauvaise réputation en sécurité.
La prochaine fois que vous implémenterez une authentification basée sur JWT, rappelez-vous : si vous ne voudriez pas que ces données apparaissent dans un fichier de logs serveur, elles ne devraient pas être dans une payload JWT. La confidentialité de vos utilisateurs et la sécurité de votre application en dépendent.
Related InstaTunnel pages
Continue from this article into the most relevant product guides and workflows.
Related Topics
Keep building with InstaTunnel
Read the docs for implementation details or compare plans before you ship.