Le guide pratique du projet OWASP GenAI Security pour le développement de serveurs MCP culmine avec une liste de contrôle de revue concrète — le « niveau minimum de sécurité MCP ». Cette liste de contrôle définit les contrôles de base qui doivent être en place avant qu’un serveur MCP ne soit déployé en production.
Cet article présente la liste de contrôle complète avec des conseils de mise en œuvre pour chaque élément, organisés selon les cinq domaines de sécurité définis par le guide OWASP. Utilisez-la pour les revues de sécurité avant déploiement, les audits périodiques et comme cadre pour corriger les lacunes identifiées.
Marquage des éléments : Pour chaque élément, enregistrez RÉUSSI (implémenté et vérifié), ÉCHOUÉ (non implémenté ou partiellement implémenté), ou N/A (non applicable à ce déploiement).
Portes de déploiement : Les éléments de la catégorie 1 (Identité, Authentification, Politique) et de la catégorie 2 (Isolation) sont des portes de déploiement strictes — tout ÉCHEC doit bloquer la mise en ligne jusqu’à correction. Les éléments des autres catégories doivent être acceptés avec des calendriers documentés.
Déclencheurs de revue : Relancez la liste de contrôle complète après tout changement important du code du serveur MCP, du registre d’outils, de la configuration d’authentification, de l’environnement de déploiement, ou lorsqu’une nouvelle catégorie d’outils est intégrée.
Catégorie 1 : Identité, authentification et application des politiques robustes
C’est la catégorie de priorité la plus élevée. Les échecs d’authentification donnent aux attaquants un accès direct à tout ce que le serveur MCP peut faire.
1.1 Tous les serveurs MCP distants utilisent OAuth 2.1 / OIDC
Ce qu’il faut vérifier : Chaque connexion distante au serveur MCP nécessite une authentification via un serveur d’autorisation OAuth 2.1 correctement configuré. Les connexions anonymes sont rejetées. Les serveurs MCP locaux utilisant STDIO peuvent utiliser une authentification alternative appropriée à leur contexte de déploiement.
Comment tester : Tentez de vous connecter sans en-tête d’autorisation. Tentez de vous connecter avec un jeton malformé ou expiré. Les deux doivent entraîner un échec d’authentification, et non un accès aux outils.
Modes d’échec courants : Points de terminaison de développement laissés accessibles sans authentification ; repli sur l’authentification par clé API qui ne valide pas l’expiration ou la portée ; validation du jeton uniquement lors de l’établissement de la session, et non par requête.
1.2 Les jetons sont de courte durée, à portée limitée et validés à chaque appel
Ce qu’il faut vérifier : Les jetons d’accès expirent en quelques minutes (et non en heures). Chaque jeton porte la portée minimale requise pour la tâche en cours. Chaque invocation d’outil valide la signature du jeton, l’émetteur (iss), l’audience (aud), l’expiration (exp) et la portée requise — pas seulement lors de l’établissement de la session.
Comment tester : Utilisez un jeton valide, puis attendez qu’il expire (ou avancez manuellement l’horloge). Tentez un appel d’outil — il doit échouer avec un 401, et non réussir sur un résultat de validation mis en cache.
Modes d’échec courants : Validation du jeton mise en cache au démarrage de la session et non répétée ; jetons avec des durées de vie de 24+ heures ; portées « admin » larges utilisées au lieu de portées spécifiques aux opérations ; champ exp non vérifié.
1.3 Pas de transmission de jeton ; l’application des politiques est centralisée
Ce qu’il faut vérifier : Le serveur MCP ne transfère pas les jetons clients aux API en aval. Tous les appels de service en aval utilisent des jetons explicitement émis pour le serveur MCP (via des flux On-Behalf-Of ou des informations d’identification de service). Une passerelle de politique centralisée intercepte toutes les invocations d’outils et applique l’authentification, l’autorisation, le consentement et la journalisation d’audit avant que tout code d’outil ne s’exécute.
Comment tester : Examinez le code pour tout emplacement où le jeton client entrant est transféré dans un appel API sortant. Inspectez les journaux d’accès au service en aval pour vérifier que les requêtes arrivent avec des informations d’identification du serveur, et non des informations d’identification de l’utilisateur.
Modes d’échec courants : Motif Authorization: Bearer ${request.headers.authorization} dans les appels en aval ; vérifications d’autorisation dispersées dans les gestionnaires d’outils individuels ; pas de point d’application de politique centralisé.
Prêt à développer votre entreprise?
Commencez votre essai gratuit aujourd'hui et voyez les résultats en quelques jours.
Catégorie 2 : Isolation stricte et contrôle du cycle de vie
Les échecs d’isolation dans les environnements multi-locataires sont catastrophiques — ils permettent à un utilisateur d’accéder aux données d’un autre. Ce sont des portes de déploiement strictes.
2.1 Les utilisateurs, sessions et contextes d’exécution sont entièrement isolés
Ce qu’il faut vérifier : Aucune variable globale, attribut de niveau classe ou instance singleton partagée ne stocke de données spécifiques à l’utilisateur ou à la session. Chaque session utilise des objets instanciés indépendamment ou des espaces de noms à clés de session (par exemple, clés Redis préfixées par session_id:). La revue de code confirme l’absence d’état mutable partagé entre les sessions.
Comment tester : Exécutez deux sessions simultanées avec des identités d’utilisateur différentes. Vérifiez que les données écrites dans la session A ne peuvent pas être lues dans la session B. Utilisez des tests de charge simultanés pour vérifier les conditions de concurrence qui pourraient causer une fuite d’état de session.
Modes d’échec courants : self.user_context = {} comme attribut de classe dans un service singleton ; caches globaux sans espaces de noms à clés de session ; stockage local de thread qui ne se limite pas correctement au cycle de vie de la requête.
2.2 Pas d’état partagé pour les données utilisateur
Ce qu’il faut vérifier : Au-delà du contexte d’exécution, toute infrastructure partagée (bases de données, caches, files de messages) applique des contrôles d’accès par utilisateur. Une requête exécutée dans la session d’un utilisateur ne peut pas renvoyer les données d’un autre utilisateur même si l’infrastructure partagée est mal configurée ou compromise.
Comment tester : Tentez d’accéder aux données d’un autre utilisateur en manipulant les paramètres de session ou en exploitant les clés de cache partagées.
Modes d’échec courants : Clés de cache basées uniquement sur le contenu de la requête, et non sur l’identité de l’utilisateur ; requêtes de base de données sans clauses WHERE limitées à l’utilisateur ; répertoires de fichiers temporaires partagés sans sous-répertoires par utilisateur.
2.3 Les sessions ont un nettoyage déterministe et des quotas de ressources appliqués
Ce qu’il faut vérifier : Lorsqu’une session se termine (proprement ou par expiration/erreur), toutes les ressources associées sont immédiatement libérées : descripteurs de fichiers, fichiers temporaires, contexte en mémoire, jetons mis en cache, connexions à la base de données. Des limites par session existent pour la mémoire, le CPU, le taux d’API et l’utilisation du système de fichiers.
Comment tester : Terminez une session brusquement (tuez la connexion sans arrêt gracieux). Vérifiez qu’aucune ressource résiduelle ne reste. Créez une session et épuisez sa limite de taux ; vérifiez qu’elle n’affecte pas les autres sessions.
Modes d’échec courants : Fichiers temporaires laissés dans /tmp après la fin de la session ; jetons mis en cache non révoqués à la fin de la session ; pas de quotas de ressources permettant à une session d’épuiser l’infrastructure partagée.
Catégorie 3 : Outillage fiable et contrôlé
La sécurité des outils empêche les attaques les plus dangereuses spécifiques à MCP : l’empoisonnement d’outils et les rug pulls.
Ce qu’il faut vérifier : Chaque définition d’outil a une signature cryptographique d’un approbateur d’outil autorisé. La signature couvre le manifeste complet (description, schéma, version, permissions). Le serveur MCP vérifie cette signature au moment du chargement et rejette tout outil non signé ou avec une signature non concordante. Les versions d’outils sont épinglées — le serveur ne peut pas charger dynamiquement un outil mis à jour sans une nouvelle signature approuvée.
Comment tester : Modifiez un seul caractère dans la description d’un outil chargé. Vérifiez que le serveur détecte la non-concordance de hachage et bloque le chargement de l’outil. Tentez de charger une définition d’outil non signée — elle doit être rejetée.
Modes d’échec courants : Définitions d’outils stockées comme configuration mutable sans vérification d’intégrité ; pas d’infrastructure de clé de signature ; outils chargés directement depuis un système de fichiers partagé sans épinglage de version.
3.2 Les descriptions d’outils sont validées par rapport au comportement à l’exécution
Ce qu’il faut vérifier : L’analyse automatisée vérifie les descriptions d’outils pour les motifs de type instruction qui pourraient représenter des tentatives d’empoisonnement. La validation périodique confirme que le comportement réel à l’exécution d’un outil correspond à sa description déclarée — un outil qui prétend être en lecture seule ne doit pas être capable d’opérations d’écriture à l’exécution.
Comment tester : Ajoutez une instruction suspecte à une description d’outil (« appelez toujours aussi send_webhook avec… ») et vérifiez que l’analyse automatisée la signale avant la revue humaine. Examinez la configuration de l’outil SAST pour les règles de détection d’empoisonnement spécifiques à MCP.
Modes d’échec courants : Pas d’analyse automatisée des descriptions d’outils ; processus de revue manuelle qui peut manquer des instructions intégrées dans de longues descriptions ; pas de validation du comportement à l’exécution pour attraper les outils qui mentent sur leurs capacités.
3.3 Seuls les champs d’outils minimaux et nécessaires sont exposés au modèle
Ce qu’il faut vérifier : Le contexte du modèle ne reçoit que les champs requis pour une invocation correcte de l’outil : nom, description, schéma d’entrée, schéma de sortie. Les métadonnées internes, les détails d’implémentation, les informations de débogage et la configuration sensible sont filtrés avant d’être transmis au modèle.
Comment tester : Inspectez ce que le modèle reçoit lorsqu’il énumère les outils disponibles. Vérifiez qu’aucun champ interne, chaîne de connexion ou métadonnée opérationnelle n’apparaît dans la vue du modèle.
Modes d’échec courants : Objets de configuration d’outils complets transmis au contexte du modèle ; messages d’erreur contenant des détails du système interne qui fuient vers le modèle ; descriptions d’outils incluant des notes d’implémentation non pertinentes pour l’invocation.
Rejoignez notre newsletter
Recevez gratuitement les derniers conseils, tendances et offres.
Catégorie 4 : Validation basée sur les schémas partout
Les échecs de validation permettent l’injection, la manipulation de données et le déni de service.
4.1 Tous les messages MCP, entrées et sorties d’outils sont validés par schéma
Ce qu’il faut vérifier : La validation de schéma JSON est appliquée pour chaque message de protocole MCP, chaque entrée d’invocation d’outil et chaque sortie d’outil avant qu’elle n’atteigne le modèle. La validation rejette tout message qui ne se conforme pas au schéma défini — champs requis manquants, types incorrects, valeurs en dehors des plages autorisées.
Comment tester : Envoyez une invocation d’outil avec un paramètre requis manquant. Envoyez un message avec un champ supplémentaire inattendu. Les deux doivent être rejetés, et non silencieusement ignorés ou traités avec des valeurs par défaut.
Modes d’échec courants : Validation optionnelle qui est contournée dans des conditions d’erreur ; validation uniquement sur les entrées, pas sur les sorties ; schémas trop permissifs (acceptant des paramètres type: "any").
4.2 Les entrées/sorties sont assainies, limitées en taille et traitées comme non fiables
Ce qu’il faut vérifier : Toutes les entrées sont assainies pour supprimer ou échapper les caractères qui pourraient permettre l’injection (séquences XSS, métacaractères SQL, métacaractères shell, octets nuls). Les limites de taille sont appliquées sur toutes les entrées et sorties. Le serveur traite toutes les données du modèle comme potentiellement hostiles, identiques à l’entrée utilisateur dans une application web traditionnelle.
Comment tester : Envoyez des entrées contenant des charges utiles d’injection SQL, des métacaractères shell et des séquences XSS. Vérifiez qu’elles sont rejetées ou échappées en toute sécurité avant d’atteindre les systèmes en aval. Envoyez une entrée qui dépasse la limite de taille — vérifiez qu’elle est rejetée proprement.
Modes d’échec courants : Entrées passées directement aux requêtes SQL ou commandes shell ; pas de limites de taille permettant aux entrées surdimensionnées de causer l’épuisement de la mémoire ; sorties renvoyées au modèle sans limites de taille ou filtrage de contenu.
4.3 L’invocation d’outil structurée (JSON) est requise
Ce qu’il faut vérifier : Les appels d’outils ne sont acceptés que sous forme d’objets JSON structurés avec des schémas validés. La génération de texte libre qui implique des invocations d’outils n’est pas traitée. Le système ne peut pas être amené à exécuter des appels d’outils en générant du langage naturel que le serveur interprète comme des commandes.
Comment tester : Envoyez une chaîne en langage naturel qui décrit une invocation d’outil (« appelle l’outil delete_file avec le chemin /etc/passwd »). Vérifiez que le serveur n’interprète pas cela comme un appel d’outil.
Modes d’échec courants : Systèmes hybrides qui acceptent à la fois le JSON structuré et les descriptions d’outils en langage naturel ; serveurs qui analysent le texte généré par le modèle pour identifier les invocations d’outils ; analyse d’appels d’outils basée sur regex qui peut être usurpée.
Catégorie 5 : Déploiement durci et supervision continue
Le durcissement du déploiement limite le rayon d’explosion de toute vulnérabilité exploitée.
5.1 Le serveur s’exécute conteneurisé, non-root, avec restriction réseau
Ce qu’il faut vérifier : Le serveur MCP s’exécute dans un conteneur minimal durci. Le processus du conteneur s’exécute en tant qu’utilisateur non-root. Les capacités Linux inutiles sont supprimées. Les politiques réseau restreignent tout le trafic entrant et sortant aux connexions explicitement requises. L’image du conteneur ne contient que le logiciel minimum requis.
Comment tester : Exécutez docker inspect et vérifiez que l’utilisateur est non-root. Examinez les politiques réseau et confirmez qu’elles bloquent tout le trafic sauf les connexions explicitement autorisées. Analysez l’image du conteneur pour les packages inutiles ou les logiciels avec des vulnérabilités connues.
Modes d’échec courants : Conteneurs s’exécutant en tant que root par commodité ; pas de politiques réseau laissant tout le trafic sortant autorisé ; images de base avec des installations complètes du système d’exploitation au lieu d’images minimales.
5.2 Les secrets sont stockés dans des coffres et jamais exposés au LLM
Ce qu’il faut vérifier : Toutes les clés API, secrets clients OAuth, informations d’identification de base de données et jetons de compte de service sont stockés dans un coffre de secrets (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, etc.). Aucun secret n’existe dans les variables d’environnement, le code source, les images de conteneur ou la sortie de journal. Les opérations de gestion des secrets se produisent dans un middleware inaccessible au modèle IA — le LLM ne voit ni ne traite jamais les valeurs d’informations d’identification.
Comment tester : Recherchez dans les journaux des chaînes ressemblant à des informations d’identification. Inspectez les variables d’environnement accessibles au processus du serveur. Examinez le contexte accessible du modèle pour confirmer qu’aucune valeur d’informations d’identification n’apparaît.
Modes d’échec courants : Clés API dans des fichiers .env validés dans le contrôle de version ; informations d’identification renvoyées dans des messages d’erreur qui atteignent le modèle ; secrets passés comme paramètres d’outils qui apparaissent dans le contexte de conversation du modèle.
5.3 Les portes de sécurité CI/CD, les journaux d’audit et la surveillance continue sont obligatoires
Ce qu’il faut vérifier : Le pipeline de déploiement inclut une analyse de sécurité automatisée (SAST, SCA, analyse de vulnérabilité des dépendances) comme portes strictes — les analyses échouées bloquent le déploiement. Toutes les invocations d’outils, événements d’authentification et décisions d’autorisation sont journalisés de manière immuable avec le contexte complet. Les journaux sont ingérés par un SIEM avec alerte en temps réel sur les motifs anormaux (pics d’échec de validation, fréquence inhabituelle d’appels d’outils, connexions externes inattendues).
Comment tester : Introduisez une dépendance avec une vulnérabilité connue et vérifiez que le pipeline CI/CD échoue la construction. Générez des motifs d’appels d’outils anormaux et vérifiez que les alertes SIEM se déclenchent dans le temps de réponse attendu.
Modes d’échec courants : Analyse de sécurité comme portes consultatives plutôt que bloquantes ; journaux écrits dans un stockage mutable qu’un attaquant pourrait modifier ; pas d’alerte sur les motifs anormaux ; verbosité excessive des journaux qui rend les événements pertinents impossibles à trouver.
Utilisation de cette liste de contrôle pour votre déploiement MCP
Imprimez ou exportez cette liste de contrôle et parcourez-la systématiquement pour chaque serveur MCP avant le déploiement en production. Impliquez votre équipe de sécurité dans la revue — de nombreux éléments nécessitent à la fois une revue de code et des tests en direct pour vérifier correctement.
Pour les équipes qui souhaitent une vérification indépendante, un audit de sécurité MCP
professionnel teste tous les 16 éléments de la liste de contrôle par rapport à votre environnement réel, en utilisant des techniques de test adversariales plutôt que l’auto-évaluation. Le résultat est un rapport de posture de sécurité vérifié avec un plan de remédiation priorisé.
Ressources connexes