Retour au blog
MCPOAuthidentitySDKtool use

MCP Python SDK : un serveur malveillant suffisait pour récupérer votre client secret

Publié le 2026-09-296 min de lectureActionShield

> En bref : Un serveur MCP malveillant pouvait tromper le client du SDK Python officiel pour qu'il envoie son client secret, son code d'autorisation et sa clé PKCE à un endpoint de token contrôlé par l'attaquant. La faille était corrigée depuis le 7 septembre dans les versions 1.30.0 et 2.2.0 — mais l'advisory date du 28 septembre : beaucoup de déploiements tournent encore sur des versions affectées.

Le mécanisme : le serveur répond à la question du client

Le flux OAuth du SDK fonctionne ainsi : le client demande au serveur MCP où se trouve le serveur d'autorisation. Le serveur répond. Et c'est là que se joue tout.

Dans les versions affectées, le SDK validait insuffisamment cette réponse. Un serveur malveillant pouvait donc renvoyer un endpoint de token contrôlé par l'attaquant — et le client y transmettait client secret, code d'autorisation et clé PKCE.

Cycode a rapporté la faille et démontré un échange de credentials complet : les identités volées s'échangent contre un access token valide portant les permissions de l'application. Et le client secret est un secret longue durée : l'échanger une fois, c'est l'avoir pour longtemps.

Qui est affecté

  • 1.x : 1.9.1 à 1.29.1 — corrigé dans 1.30.0
  • 2.x : 2.0.0 à 2.1.1 — corrigé dans 2.2.0
  • Les providers affectés : OAuthClientProvider, ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, et le provider obsolète RFC7523OAuthClientProvider en 1.x. CVSS 7.5 pour les deux providers non interactifs, 6.5 pour le provider interactif. Pas de CVE attribué à ce jour, pas d'attaque active connue.

    Ce que l'upgrade ne fait pas

    C'est le point que la plupart des équipes vont rater :

  • `ClientCredentialsOAuthProvider` et `PrivateKeyJWTOAuthProvider` exigent désormais un paramètre `issuer=` après l'upgrade. Sans lui, la correction ne s'applique pas.
  • `RFC7523OAuthClientProvider` n'a pas de `issuer=` : il est obsolète, il faut migrer.
  • Nettoyer une fois l'enregistrement OAuth client sauvegardé après l'upgrade — sinon le client rechargera l'ancienne réponse de découverte.
  • Si votre client s'est connecté à un serveur non fiable : faire tourner le client secret et révoquer les tokens. L'upgrade ne rattrape pas ce qui a déjà été transmis.
  • En 1.30.0, l'avertissement est un simple deprecation warning Python, masqué par défaut. Il ne clignote nulle part.

    Ce qu'il faut vérifier maintenant

  • Listez vos versions du SDK MCP Python dans chaque client qui s'authentifie via OAuth. 1.9.1 et plus tard, 2.0.0 et plus tard : affecté.
  • Vérifiez que `issuer=` est passé pour les providers non interactifs, après l'upgrade.
  • Identifiez les serveurs MCP que vos clients ont contactés — « non fiable » inclut tout serveur que vous n'avez pas déployé vous-même.
  • Ce qui n'est pas affecté : les serveurs MCP construits avec le SDK, les clients stdio locaux, et les clients qui attachent leurs propres tokens.
  • La leçon

    Dans le flux OAuth, le serveur MCP est la partie la moins fiable de la chaîne — et pourtant, c'est lui qui décide où le client envoie ses secrets. Un client qui fait confiance à la réponse de découverte de n'importe quel serveur, c'est la même erreur qu'un navigateur qui suit une redirection sans vérifier. La règle simple : une identité ne doit jamais dépendre de la réponse d'un tiers non contrôlé.

    Vous éditez un logiciel ? CleanIssue réalise des audits de sécurité pour votre produit en conditions réelles, sans accès au code. Pour une première lecture de votre exposition, commencez par une revue externe de votre application.

    Besoin de savoir ce que votre agent IA peut faire ?

    Expliquez votre agent, ses tools et votre contexte client. Nous revenons vers vous avec le bon niveau de revue.

    Parler de votre audit