L’authentification est le gardien qui détermine si les capacités puissantes d’un serveur MCP sont disponibles pour des utilisateurs légitimes ou pour des attaquants. Si vous vous trompez, tous les autres contrôles de sécurité deviennent inutiles — un serveur MCP non authentifié ou mal authentifié avec accès aux e-mails, fichiers et bases de données est une vulnérabilité critique, quelle que soit la qualité du renforcement de tout le reste.
Le guide du projet OWASP GenAI Security identifie l’authentification et l’autorisation comme l’un des huit domaines de sécurité principaux pour les serveurs MCP, avec des exigences spécifiques qui vont au-delà de ce que la plupart des développeurs implémentent par défaut. Cet article explique pourquoi ces exigences existent et comment les implémenter correctement.
Le Défi de l’Authentification dans MCP
Les serveurs MCP font face à un paysage d’authentification plus complexe que les services traditionnels car ils assurent la médiation entre plusieurs principaux :
- L’utilisateur dont les instructions dirigent l’assistant IA
- Le modèle IA qui interprète les instructions et appelle les outils
- Le client MCP (l’application hébergeant l’IA)
- Le serveur MCP qui exécute les appels d’outils
- Les services en aval que le serveur MCP appelle au nom de l’utilisateur
Chacune de ces relations nécessite ses propres contrôles d’authentification et d’autorisation. Une faiblesse dans n’importe quel maillon peut être exploitée pour contourner les autres.
Obligatoire : OAuth 2.1 et OIDC pour les Serveurs Distants
Pour les serveurs MCP distants — ceux accessibles via un réseau plutôt que par STDIO local ou sockets Unix — le guide OWASP GenAI est sans ambiguïté : OAuth 2.1 avec OIDC est obligatoire, pas optionnel.
Cette exigence existe parce que :
OAuth 2.1 fournit un contrôle de portée explicite. Chaque jeton d’accès déclare exactement quelles ressources et actions il autorise. Un serveur MCP peut vérifier au moment de l’invocation de l’outil que le jeton présenté a la portée spécifique nécessaire pour cette action — pas seulement que l’utilisateur est authentifié, mais qu’il est autorisé pour cette opération spécifique.
OIDC fournit une identité cryptographique. OpenID Connect ajoute des assertions d’identité (le jeton ID) que le serveur MCP peut vérifier sans aller-retour vers le fournisseur d’identité. Le serveur valide l’iss (émetteur), l’aud (audience), l’exp (expiration) et la signature sur chaque requête.
Les jetons OAuth 2.1 sont de courte durée par conception. La spécification OAuth moderne (qui consolide et remplace les meilleures pratiques OAuth 2.0) met l’accent sur les jetons d’accès de courte durée qui doivent être régulièrement rafraîchis. Cela limite la fenêtre de dommages si un jeton est compromis.
Que Valider sur Chaque Requête
Ne validez pas les jetons uniquement lors de l’établissement de la session. Validez à chaque invocation d’outil :
def validate_token(token: str, required_scope: str) -> TokenClaims:
claims = jwt.decode(
token,
key=get_public_key(claims_preview['kid']),
algorithms=["RS256", "ES256"]
)
assert claims['iss'] == EXPECTED_ISSUER
assert EXPECTED_AUDIENCE in claims['aud']
assert claims['exp'] > time.time()
assert required_scope in claims['scope'].split()
return claims
Ne mettez jamais en cache les résultats de validation entre les requêtes. Un jeton qui était valide au début de la session peut être révoqué en milieu de session.
Environnements de Clients Dynamiques
Dans les environnements où les clients MCP changent fréquemment (par exemple, différents assistants IA se connectant au même serveur), les clés API statiques ou les secrets pré-partagés sont insuffisants. Utilisez l’enregistrement de client dynamique avec OAuth 2.1 ou OIDC pour vérifier l’identité du client au moment de la connexion. Les listes d’autorisation, les politiques de connexion codées en dur ou le TLS mutuel (mTLS) sont appropriés pour les relations statiques connues entre clients et serveurs spécifiques.
Prêt à développer votre entreprise?
Commencez votre essai gratuit aujourd'hui et voyez les résultats en quelques jours.
Le Problème du Député Confus
Comprendre l’Attaque
Le Député Confus est une vulnérabilité d’autorisation classique avec une manifestation particulièrement dangereuse dans les architectures MCP. L’attaque exploite l’ambiguïté de l’autorité de qui le serveur MCP agit.
Considérez ce scénario :
- L’utilisatrice Alice est authentifiée sur un serveur MCP avec des permissions limitées — elle peut lire ses propres fichiers mais pas ceux des autres
- Le serveur MCP a de larges permissions de compte de service pour lire tous les fichiers de l’organisation
- Le serveur MCP utilise le passage de jeton : il transmet le jeton d’Alice aux services en aval
Lorsque Alice demande à l’assistant IA de “résumer mon dossier de projet”, le serveur utilise le jeton d’Alice pour accéder à ses fichiers — comportement correct. Mais si un attaquant trompe le serveur pour qu’il fasse une requête en utilisant ses propres identifiants de service (peut-être par une attaque d’empoisonnement d’outil ou une injection de prompt indirecte), les permissions élevées du serveur sont utilisées pour accéder à des fichiers qu’Alice n’est pas autorisée à voir.
Le serveur est le “député confus” — il a été trompé pour utiliser son autorité au nom de quelqu’un qui n’a pas cette autorité, agissant comme un proxy pour l’escalade de privilèges.
Pourquoi le Passage de Jeton Crée Cette Vulnérabilité
De nombreuses implémentations MCP transmettent le jeton du client aux API en aval par simplicité. Cela semble intuitif — le jeton de l’utilisateur représente les permissions de l’utilisateur, donc l’utiliser pour tous les appels en aval maintient un contrôle d’accès correct.
Le problème : les API en aval qui reconnaissent le serveur MCP comme un intermédiaire de confiance peuvent accorder des requêtes en utilisant le niveau d’identité du serveur, et non le niveau du jeton utilisateur transmis. Et si le serveur MCP agit de sa propre initiative — par une prise de décision IA que l’utilisateur n’a pas explicitement demandée — il peut utiliser ses propres identifiants plutôt que le jeton de l’utilisateur.
La transmission de jetons utilisateur :
- Brise les pistes d’audit (les journaux en aval montrent l’identité de l’utilisateur, pas l’identité du serveur, obscurcissant la couche MCP)
- Donne à un attaquant qui compromet le serveur MCP l’accès à tous les jetons utilisateur transmis
- Crée des problèmes de conformité si les jetons pour différents utilisateurs peuvent être confondus ou rejoués
La Solution : Délégation Explicite de Jetons avec les Flux On-Behalf-Of
Au lieu de transmettre les jetons clients, le serveur MCP devrait obtenir ses propres jetons pour l’accès au service en aval en utilisant le flux On-Behalf-Of (OBO) d’OAuth :
L'utilisateur s'authentifie auprès du client MCP → le client obtient le jeton d'accès utilisateur
Le client MCP présente le jeton utilisateur au serveur MCP
Le serveur MCP échange le jeton utilisateur contre un jeton serveur via le flux OBO :
POST /token
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
assertion=<user_access_token>
scope=<minimum_required_scope>
Le serveur MCP utilise son propre jeton OBO pour les appels en aval
Le jeton OBO :
- Est explicitement limité aux permissions minimales nécessaires pour l’appel d’outil spécifique
- Identifie le serveur MCP comme la partie appelante (avec l’utilisateur comme sujet)
- Est lié à l’événement d’authentification de l’utilisateur (peut être révoqué lorsque la session de l’utilisateur se termine)
- N’expose pas le jeton complet de l’utilisateur aux services en aval
Jetons de Courte Durée et à Portée Limitée
Le guide OWASP GenAI fait une recommandation spécifique : émettre des jetons d’accès avec des durées de vie mesurées en minutes, pas en heures. Cela s’applique à la fois aux jetons que le serveur MCP accepte des clients et aux jetons qu’il obtient pour l’accès au service en aval.
Pourquoi les Durées Courtes Importent
Un jeton d’accès volé est valide pendant toute sa durée de vie, que l’utilisateur légitime se soit déconnecté, ait changé son mot de passe ou révoqué sa session. Un jeton de 24 heures volé au début d’une session donne à un attaquant 24 heures d’accès persistant. Un jeton de 5 minutes volé en milieu de session donne au maximum 5 minutes.
Les jetons de courte durée imposent également des événements de réauthentification réguliers, qui offrent des opportunités de :
- Revérifier si le compte de l’utilisateur a été suspendu ou si ses permissions ont changé
- Détecter des modèles d’authentification anormaux (heures, lieux ou fréquence inhabituels)
- Appliquer une authentification renforcée pour les opérations sensibles
Minimisation de la Portée des Jetons
Chaque jeton ne devrait porter que les portées nécessaires pour l’opération spécifique en cours d’exécution. N’émettez pas un jeton avec une portée read:files write:files delete:files lorsque l’appel d’outil actuel n’a besoin que de read:files. Cela limite les dommages si le jeton est intercepté ou si le modèle est manipulé pour faire des appels d’outils inattendus.
def get_tool_token(user_id: str, tool_name: str) -> str:
# Mapper l'outil aux portées minimales requises
required_scopes = TOOL_SCOPE_MAP[tool_name]
return oauth_client.get_token(
subject=user_id,
scopes=required_scopes,
lifetime_seconds=300 # durée de vie de 5 minutes
)
Rejoignez notre newsletter
Recevez gratuitement les derniers conseils, tendances et offres.
Traiter les Sessions comme un État, Pas une Identité
Une erreur courante consiste à utiliser les ID de session comme proxys d’autorisation : si une requête porte un ID de session valide, le serveur suppose qu’elle est autorisée. Cela confond la gestion de l’état avec la vérification de l’identité.
Le modèle correct : les ID de session gèrent l’état conversationnel. L’autorisation est vérifiée indépendamment sur chaque requête en validant les revendications du jeton OAuth. Même une requête portant un ID de session valide doit présenter un jeton OAuth valide, non expiré et correctement limité avant que toute invocation d’outil ne soit autorisée.
Cela importe car les ID de session peuvent être volés, devinés ou rejoués de manières que les jetons OAuth — qui portent des garanties d’intégrité cryptographique — ne peuvent pas.
Application Centralisée des Politiques
Plutôt que d’implémenter des vérifications d’autorisation dispersées dans les gestionnaires d’outils individuels, le guide OWASP GenAI recommande une passerelle de politique centralisée qui :
- Intercepte toutes les requêtes d’invocation d’outils avant qu’elles n’atteignent le code spécifique à l’outil
- Valide l’authentification (signature du jeton, émetteur, audience, expiration)
- Applique l’autorisation (portée requise pour cet outil spécifique)
- Applique la vérification du consentement (l’utilisateur a-t-il explicitement autorisé ce type d’action ?)
- Implémente le filtrage des outils (cet outil est-il autorisé dans ce contexte de déploiement ?)
- Enregistre toutes les décisions avec le contexte complet pour l’audit
La centralisation garantit que les politiques sont appliquées de manière cohérente sur tous les outils et agents. Une vérification d’autorisation spécifique à un outil peut être oubliée ou contournée pendant le développement ; une vérification de passerelle ne le peut pas.
Résumé : La Liste de Contrôle d’Authentification
Pour les serveurs MCP distants, le niveau minimum de sécurité d’authentification est :
Ressources Connexes