Aller au contenu

Injection d'en-tête X5C JWT

GravitéÉlevée
ClassificationsCWE-295: Improper Certificate Validation
Schéma d’attaqueCAPEC-194: Fake the Source of Data
Catégorie OWASPOWASP API2:2023 Broken Authentication

Le champ d’en-tête JWT x5c (RFC 7515 §4.1.6) permet à un token d’embarquer la chaîne de certificats X.509 correspondant à la clé utilisée pour le signer, encodée en base64 (pas en base64url). Il existe pour qu’un vérificateur puisse valider le certificat du signataire contre un magasin de confiance sans devoir faire une recherche séparée. Les serveurs qui extraient la clé publique depuis x5c et l’utilisent pour vérifier la signature — sans valider aussi la chaîne de certificats jusqu’à une racine de confiance épinglée — accepteront un certificat que l’attaquant a généré lui-même.

Un attaquant qui exploite cette faille de confiance génère sa propre paire de clés et un certificat auto-signé jetable, intègre le certificat dans l’en-tête x5c, puis signe le token avec la clé privée correspondante. Comme le serveur extrait et utilise la clé publique du certificat fourni par l’attaquant pour vérifier la signature fournie par l’attaquant, la vérification réussit toujours — pour n’importe quels claims choisis par l’attaquant.

C’est la même classe de défaillance de confiance que l’injection d’en-tête JWK (CVE-2018-0114) — la différence porte sur le format de la clé : un JWK brut contre un certificat X.509. C’est aussi étroitement lié à l’injection d’en-tête X5U, qui récupère le certificat depuis une URL hébergée par l’attaquant au lieu de l’embarquer directement.

Voici un JWT valide signé en RS256 avec la vraie clé du serveur :

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.<signature>

L’attaquant génère une nouvelle paire de clés RSA et un certificat auto-signé, intègre le certificat dans x5c, ajuste kid pour correspondre, et re-signe avec la clé privée :

{
"alg": "RS256",
"typ": "JWT",
"kid": "x5c-injection",
"x5c": ["MIIC5jCCAc6gAwIBAgIQ..."]
}

Un serveur vulnérable décode le certificat depuis x5c, en extrait la clé publique, vérifie la signature avec elle (ce qui réussit — l’attaquant a signé avec la clé privée correspondante), et considère le token comme authentique — sans vérifier si le certificat remonte jusqu’à une AC en laquelle il a réellement confiance.

Si vous voulez tester si votre serveur est vulnérable à la vulnérabilité « JWT X5C Header Injection », vous pouvez utiliser la commande crack :

Terminal window
jwtop crack [token] --url [url]

Le contrôle ne s’exécute que sur les tokens RSA/ECDSA (RS*/ES*/PS*) — un serveur qui fait confiance à un certificat x5c embarqué n’a aucune raison de le faire pour des tokens signés en HMAC.

Pour générer un token avec un certificat x5c auto-signé injecté, utilisez la commande exploit x5cinjection :

Terminal window
jwtop exploit x5cinjection [token]

Une attaque par injection X5C réussie permet à un attaquant de forger un JWT que le serveur accepte comme légitime, sans aucune connaissance de la clé de signature réelle du serveur. Cela peut mener à un contournement complet de l’authentification, une élévation de privilèges, ou l’usurpation de n’importe quel utilisateur du système.

  • Ne résolvez jamais la clé de vérification depuis le token lui-même. Ignorez les champs d’en-tête x5c (ainsi que jwk, jku, x5u) lors de la vérification — recherchez la clé côté serveur via kid dans un jeu de clés ou un magasin de certificats épinglé.
  • Si le support de x5c est incontournable, validez la chaîne de certificats complète jusqu’à une AC racine de confiance épinglée — ne faites jamais confiance à un certificat simplement parce qu’il se parse correctement ou qu’il est cohérent en interne.
  • Épinglez l’algorithme et la ou les clés attendus par émetteur afin qu’un token ne puisse pas dicter quelle clé, quelle famille d’algorithme, ou quel certificat le vérifie.