Catégories

Tags

🔍 Licence d'Utilisation 🔍

Sauf mention contraire, le contenu de ce blog est sous licence CC BY-NC-ND 4.0.

© 2025 à 2042 Sébastien Gioria. Tous droits réservés.

⏱️
Temps de lecture estimé
4 min de lecture
⏱️
Temps de lecture estimé
~4 minutes

Deux jours après l’advisory du SDK Python, le SDK TypeScript officiel du MCP tombe sur la même classe de faille : un serveur MCP malveillant désigne son propre serveur d’autorisation, et le client lui remet refresh_token et client_secret sans la moindre interaction. CVE-2026-104850, CVSS 7.5, corrigée en 1.31.0 et 2.2.0, et la mise à jour seule ne suffit pas.

Source : GHSA-6qxp-vccf-f47h, modelcontextprotocol/typescript-sdk, publiée le 30 septembre 2026 ; CVE-2026-104850 publiée le 6 octobre 2026.

Prenez un agent qui tourne la nuit dans votre CI. Il est branché sur trois serveurs MCP internes, authentifié en client_credentials auprès de votre IdP, et quelqu’un lui a ajouté la semaine dernière un quatrième serveur, trouvé dans un registre public, « pour tester ». Au premier appel, ce quatrième serveur répond 401 et indique où trouver ses métadonnées. Elles désignent un serveur d’autorisation. Pas le vôtre : le sien. Le client du SDK suit, et présente à ce serveur le client_secret que vous aviez configuré pour votre IdP. Pas d’écran de consentement, pas de pop-up, pas d’humain. Le matin, le journal de la CI affiche peut-être une erreur d’authentification. Peut-être même pas.

Note du PandaRedacteur : deux SDK officiels, deux langages, deux équipes de rapporteurs, la même classe de faille, deux advisories à deux jours d’écart. Une fois, on parle de bug. Deux fois, on parle de motif. Et un motif se corrige à la conception ; un changelog n’y suffira pas.

Rappel : le SDK Python

Le 30 septembre, l’article sur le SDK Python décrivait la première manche : le client ne vérifiait pas correctement quel serveur d’autorisation lui répondait, ce qui permettait à un serveur MCP malveillant de récupérer le client secret, l’authorization code et la preuve PKCE. Le SDK TypeScript appartient à la même famille, le mix-up attack documenté par Fett, Küsters et Schmitz en 2016. L’advisory TypeScript ne mentionne pas le SDK Python : le rapprochement repose sur le mécanisme, pas sur une filiation déclarée.

Ce que dit l’advisory

  • Identifiants : CVE-2026-104850, GHSA-6qxp-vccf-f47h. Advisory publiée le 30 septembre 2026, CVE publiée le 6 octobre.
  • Score : CVSS 3.1 de 7.5 (High), vecteur CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N. Faiblesses : CWE-345 et CWE-522.
  • Exposition réelle : EPSS à 0,18 % sur 30 jours, absente du catalogue CISA KEV, aucun PoC public repéré au 6 octobre.
  • Paquets : @modelcontextprotocol/sdk de 1.12.0 à 1.30.1, corrigé en 1.31.0 ; @modelcontextprotocol/client de 2.0.0 à 2.1.0, corrigé en 2.2.0.
  • Ce qui part : refresh_token et client_secret d’une connexion précédente (1.x), ou le secret et l’assertion signée des providers non interactifs (1.x et 2.x), sans interaction utilisateur.
  • Hors champ : les serveurs MCP construits avec le SDK et les clients stdio.

Au Menu de la version abonnés Substack, vous retrouvez la suite :

  • le mécanisme pas à pas, avec le diagramme de séquence du client qui présente ses identifiants au serveur d’autorisation choisi par l’attaquant ;
  • ce qui part exactement : refresh_token, client_secret, assertions signées, et pourquoi le verrou du refresh token fait partie du même colis ;
  • le vrai défaut : ce que disent (et ne disent pas) la RFC 9728, la spécification MCP, la RFC 9207 et la RFC 9700, et les deux PR du SDK ;
  • le tableau de comparaison entre le SDK Python et le SDK TypeScript ;
  • l’analyse STRIDE et le tableau d’impact détaillés ;
  • les sept mitigations, de la mise à jour à la détection côté IdP, dans l’ordre ;
  • ce que le correctif ne couvre pas ;
  • le volet DevSecOps : l’issuer comme configuration, pas comme découverte ;
  • et la sketchnote en anglais du PandaRedacteur résumant tout cela.
📬 Analyse complète réservée aux abonnés Substack
Le mécanisme, le comparatif Python/TypeScript, le STRIDE et les mitigations partent d'abord aux abonnés Substack, avant d'être publiés intégralement ici.

📚 Quelques références pour aller plus loin


À retenir 📌

  • ✓ Le serveur MCP désignait le serveur d'autorisation qui recevait vos identifiants : CVE-2026-104850, CVSS 7.5, sans interaction utilisateur.
  • ✓ Le butin se suffit à lui-même : refresh_token et client_secret partent ensemble, ou le secret et l'assertion signée des providers machine.
  • ✓ Mettre à jour ne suffit pas : passer expectedIssuer aux providers fournis, migrer ou purger les identifiants stockés sans issuer, revoir les providers custom.