# Checklist sécurité MCP : 33 contrôles pour la découverte et la passerelle

> Une checklist notée pour le Model Context Protocol : trouver les serveurs MCP déjà lancés sur les postes, puis encadrer ce que les agents IA peuvent atteindre. Pondérée, neutre, gratuite.

Source: https://www.lutril.com/fr/mcp-checklist
Contrôles: 33
Poids total: 770

---

MCP a fait de chaque outil SaaS quelque chose qu'un agent IA peut appeler, et presque tout est arrivé sans ticket. Deux surfaces décident de la suite : les serveurs déjà lancés sur les postes, qu'aucun fournisseur d'identité ni journal réseau ne nommera jamais, et la passerelle entre un agent et les systèmes qui comptent.

Descendez la liste. Chaque contrôle confirmé retire son poids du score d'exposition. Rien n'est envoyé nulle part, votre progression reste dans ce navigateur.

## 01. Découvrir ce qui tourne déjà

La plupart des serveurs MCP sont des processus locaux qu'un client IA de bureau lance depuis un fichier de configuration dans un répertoire personnel. Ils détiennent des identifiants de longue durée, ils ne sont pas isolés, et aucun fournisseur d'identité, aucun CASB ni aucun journal réseau ne les nommera jamais.

- **Les postes sont analysés, pas seulement le réseau** (critique, 35) Un serveur local lancé en stdio n'ouvre aucune connexion sortante visible. Si la découverte s'arrête au trafic et aux journaux de connexion, toute la surface locale reste invisible, y compris les serveurs sur un poste où personne ne s'est connecté depuis des mois.
- **Aucun identifiant n'est écrit en clair dans une configuration client** (critique, 30) Une clé d'API tapée dans un fichier JSON est un identifiant sans rotation, sans expiration et sans responsable. Remplacez la valeur littérale par une référence d'environnement et déplacez le secret dans le trousseau du système.
- **Toute configuration contenant un identifiant est lisible par son seul propriétaire** (élevé, 20) Sur macOS, tous les comptes partagent le groupe staff : une configuration lisible par le groupe est un secret partagé. Passez le fichier en lecture propriétaire, puis renouvelez le secret, car un autre compte local a pu le lire.
- **Aucun identifiant n'est passé en argument de ligne de commande** (élevé, 15) La liste des processus est lisible par tous les comptes de la machine. Un jeton dans les arguments est un jeton que tout le monde possède déjà en local, et il se retrouve aussi dans l'audit de création de processus et les transcriptions de shell.
- **Aucun fichier de configuration n'est modifiable par un autre compte** (critique, 30) Une configuration modifiable, ou un dossier parent modifiable, permet à un attaquant local d'ajouter un serveur que le client charge sans nouvelle demande. Des failles documentées en 2026 fonctionnaient exactement ainsi.
- **Aucun conteneur MCP ne monte le socket Docker ni ne tourne en mode privilégié** (critique, 35) Le socket Docker de l'hôte équivaut à root sur la machine, et le mode privilégié retire l'essentiel de ce qu'un conteneur isole. L'un ou l'autre rend la frontière du conteneur décorative.
- **Les serveurs de fichiers sont limités à un projet, jamais à la racine ni au répertoire personnel** (critique, 30) Un serveur de fichiers enraciné au répertoire personnel transforme chaque fichier lisible par le compte en contexte pour le modèle, atteignable par tout ce qui peut influencer ce que le modèle lit.
- **Les paquets sont épinglés, et rien n'est téléchargé puis exécuté au lancement** (élevé, 20) Un lanceur npx ou uvx récupère le paquet depuis le registre et l'exécute à chaque démarrage : une version compromise arrive sans le moindre changement de configuration. Installez une fois à une version exacte, ou épinglez une empreinte.
- **Les serveurs distants utilisent https et une authentification que vous savez nommer** (élevé, 25) Le http simple envoie l'identifiant en clair sur le réseau. Un serveur distant sans jeton dans sa configuration utilise soit un flux OAuth qui stocke le jeton ailleurs, soit rien d'autre que son URL pour se protéger.
- **Une définition qui change après approbation déclenche une alerte** (critique, 35) La commande, les arguments, les noms de variables ou l'hôte peuvent tous changer sur une entrée que vous avez déjà approuvée. C'est ainsi qu'un serveur revu devient hostile, et c'est la moitié du travail qu'un inventaire ponctuel ne peut pas faire.

## 02. Encadrer ce que l'agent peut vraiment faire

Une passerelle vaut par ce qu'elle refuse. Voici les garde-fous qui tiennent quand un agent se trompe, quand un jeton est rejoué, et quand un outil désactivé ce matin est toujours enregistré sur une session ouverte.

- **L'identité du locataire vient du jeton vérifié et de nulle part ailleurs** (critique, 35) Jamais d'un en-tête, d'un paramètre d'URL ni d'un corps de requête. Une seule indication acceptée de l'appelant est une lecture inter-locataires, et c'est la base de données qui doit faire autorité sur l'isolation, pas le code applicatif.
- **L'autorisation est en OAuth 2.1, avec PKCE et rotation des jetons de rafraîchissement** (élevé, 25) Le consentement est mémorisé par personne, par client et par serveur : cinq serveurs ne font pas cinq allers-retours dans le navigateur. Le contrôle inter-locataires se fait au démarrage de l'autorisation puis de nouveau au consentement, car un serveur peut changer pendant qu'un ticket est encore valide.
- **Les jetons sont rattachés à un seul serveur** (critique, 30) L'audience est l'URL du serveur et une seconde revendication porte son identifiant, toutes deux dérivées à l'émission pour que le rafraîchissement ne puisse pas dériver. Un jeton émis pour un serveur est refusé sur tous les autres, et un ancien jeton sans revendication de serveur est refusé partout.
- **Chaque intégration est adressable pour elle-même** (élevé, 20) Un serveur par intégration, chacun avec sa ressource protégée, son état, son inventaire d'outils et sa traçabilité. Un point d'entrée unique fait de chaque autorisation une autorisation générale et de chaque ligne de journal une ambiguïté.
- **Une écriture exige une autorisation explicite qu'aucun rôle ne contourne** (critique, 30) Un propriétaire n'est pas une exception. Une autorisation d'écriture enregistrée qui ne nomme pas son approbateur a été accordée automatiquement sous une ancienne politique : elle est nulle. Quand plusieurs garde-fous lisent la même autorisation, c'est le plus faible qui décide.
- **La liste des outils est la surface de permission** (élevé, 25) Un outil que l'appelant n'a pas le droit d'exécuter n'est jamais enregistré. Le modèle reçoit donc les vrais paramètres de chaque outil au lieu d'un objet vague, et ne perd jamais un tour sur un appel qui sera refusé.
- **La classe de risque d'un outil est lue à chaque appel, jamais à l'ouverture de session** (critique, 30) Les sessions survivent aux décisions. Si le garde-fou lit la valeur capturée à la connexion du client, un administrateur qui désactive ou reclasse un outil ne change rien tant que ce client ne se déconnecte pas.
- **L'appel part avec l'identifiant de l'appelant chez l'éditeur** (élevé, 20) L'audit de l'éditeur nomme alors la personne, et ses propres droits chez l'éditeur bornent l'appel. Un identifiant manquant donne une réponse structurée qui indique l'URL de connexion, sans repli silencieux sur une connexion partagée.
- **Les serveurs tiers sont revalidés à chaque appel, redirections comprises** (critique, 30) Un hôte qui résout publiquement aujourd'hui peut résoudre vers une adresse lien-local demain, et un client HTTP par défaut suit les redirections sans revérifier la destination. Validez, résolvez et fixez chaque saut, et exigez https, car l'appel transporte l'identifiant.
- **La révocation couvre les jetons déjà émis et ceux qui ne le sont pas encore** (élevé, 25) Une date de coupure invalide l'existant, un blocage refuse d'en émettre d'autres, et les deux sont vérifiés à la validation comme sur les deux chemins d'émission. Sinon, un utilisateur révoqué se contente de rafraîchir.
- **Rien de l'amont ne ressort** (élevé, 20) Ne renvoyez jamais les jetons de l'éditeur, ne répercutez jamais l'en-tête d'autorisation et ne reflétez jamais le corps d'une erreur amont. C'est un message reflété qui transforme une falsification de requête aveugle en falsification lisible.
- **Une synchronisation d'outils en échec ne change rien** (moyen, 15) Si une erreur de synchronisation s'écrit comme un inventaire vide, un jeton éditeur expiré se lit comme un éditeur qui aurait supprimé tous ses outils, et la passerelle désactive en silence une intégration qui fonctionne.

## 03. Le prouver, et dire ce que vous ne pouvez pas prouver

La partie qui décide si tout le reste survit à un audit, à un départ ou à un lundi matin. Elle inclut les limites qui méritent d'être dites, parce qu'un contrôle qui en promet trop sans le dire est pire qu'un contrôle dont vous savez qu'il vous manque.

- **Chaque appel est journalisé jusqu'à l'outil éditeur atteint** (élevé, 25) L'acteur, le locataire, le serveur, l'outil appelé et l'outil amont relayé, avec les volumes échangés. Un journal qui s'arrête à la frontière de la passerelle ne peut pas dire qui a déplacé l'enregistrement.
- **Les accès sont limités dans le temps et repris à l'échéance** (élevé, 20) Une expiration qui dépend de la mémoire de quelqu'un n'est pas une expiration. Le balayage qui retire l'accès doit écrire la même ligne d'audit qu'un retrait manuel.
- **Les demandes et les approbations fonctionnent dans Slack, Microsoft Teams et l'application** (élevé, 20) Une décision, une ligne d'audit, trois portes d'entrée. Un parcours qui n'existe que dans l'une des trois renvoie la moitié de l'entreprise vers l'e-mail, et cette moitié ne laisse aucune trace.
- **Il existe un coupe-circuit et quelqu'un l'a testé ce trimestre** (critique, 30) Par agent et par locataire, effectif sur les jetons déjà en circulation. Un coupe-circuit jamais testé est une diapositive, pas un contrôle.
- **Chaque agent a un responsable humain nommé** (moyen, 15) Une identité non humaine sans responsable survit à chaque départ, à chaque revue d'accès et à chaque réorganisation. C'est le responsable qui rend les autres contrôles actionnables.
- **Approuver une définition ne referme jamais un constat sur une copie précise** (élevé, 20) Cette commande avec ces noms de variables est acceptable. Ce n'est pas la même phrase que ce poste-ci écrit le jeton en clair est acceptable. Gardez les constats de définition et les constats d'installation dans deux compteurs distincts.
- **Une analyse incomplète ne retire aucun serveur** (moyen, 10) Un fichier verrouillé ou une permission disque manquante ne doit pas faire disparaître des serveurs. Un inventaire qui retire en silence ce qu'il n'a pas pu lire annonce des progrès que personne n'a faits.
- **L'attribution est affichée comme déduite** (moyen, 10) Une analyse de poste ne peut pas prouver qui utilise une machine. Affichez l'adresse connectée comme un indice avec sa source, et laissez un administrateur la corriger, au lieu de l'écrire comme une identité établie.
- **Renoter le parc est un changement côté serveur** (moyen, 15) Le poste doit émettre des observations issues d'un vocabulaire figé et laisser le serveur détenir les poids. Sinon, changer d'avis sur un risque revient à pousser un nouveau binaire sur chaque ordinateur.
- **L'agent sur le poste n'exécute jamais ce qu'il découvre** (moyen, 15) Il lit des fichiers de configuration qu'un attaquant a pu écrire. Exécuter ce qu'ils nomment est exactement la vulnérabilité qu'il existe pour signaler : l'analyseur ne doit disposer d'aucun moyen d'exécution, garanti par un test et non par une relecture.
- **La version de notation est enregistrée sur chaque ligne** (moyen, 10) Quand un poids change, il faut retrouver exactement les constats jugés par l'ancien moteur. Sans numéro de version, une renotation est une supposition et une courbe de tendance une fiction.

## D'où viennent les poids

Les poids de découverte répondent aux trois questions que pose vraiment un serveur MCP local : où l'identifiant est stocké, ce que le processus atteint sous le compte de l'utilisateur puisqu'un serveur local n'est pas isolé, et si le paquet est épinglé et attribuable. Le Top 10 MCP de l'OWASP fournit le reste. C'est un document Incubator, donc traité comme provisoire.

Les contrôles de passerelle viennent de l'exploitation d'une passerelle réelle : jetons rattachés à un serveur, consentement par personne et par serveur, autorisations d'écriture qui nomment leur approbateur, inventaire d'outils qui sert de surface de permission. Plusieurs existent parce que la version évidente était fausse en premier.

Chaque contrôle de cette liste se vérifie sans Lutril. Nous automatisons ce qui ne survit pas à un tableur : un agent en lecture seule qui trouve les serveurs locaux sur macOS, Linux et Windows, la détection de dérive sur les définitions déjà approuvées, et une passerelle qui tient ces garde-fous à chaque appel.

## Questions sur la checklist

### Comment le score d'exposition est-il calculé ?

Chaque contrôle porte un poids de 10 à 35 points, fixé selon ce que permet la faille qui se cache derrière. Le score est la part de poids non confirmé, exprimée de 0 à 100 : il part donc de 100 et descend à mesure que vous confirmez. Confirmer les seuls contrôles critiques le ramène à 51.

### Pourquoi la checklist couvre-t-elle les postes et pas seulement la passerelle ?

Parce que la plupart des serveurs MCP n'atteignent jamais une passerelle. Ce sont des processus stdio lancés par Cursor, Claude Desktop ou VS Code depuis un fichier de configuration, avec un jeton de longue durée et aucune connexion sortante qu'un outil réseau pourrait voir. Une passerelle gouverne ce qu'on y fait passer, et rien d'autre.

### Faut-il un produit pour la dérouler ?

Non. Chaque contrôle est une affirmation que vous vérifiez en lisant un fichier de configuration, une revendication de jeton ou une ligne de journal. Un tableur noté suffit à une équipe pour la dérouler une fois. Ce qu'un tableur ne sait pas faire, c'est remarquer qu'une définition approuvée a changé le mois suivant, qui est le contrôle le plus lourd de la liste.

### Ma progression est-elle envoyée quelque part ?

Non. Cocher un contrôle écrit dans le stockage local de ce navigateur et nulle part ailleurs. Il n'y a ni compte, ni formulaire, ni suivi des contrôles que vous confirmez. Le bouton de copie place les contrôles restants dans votre presse-papiers en texte brut, pour les coller dans votre propre outil.

### Qu'est-ce que confirmer un contrôle ?

Avoir vérifié l'état actuel et constaté qu'il tient, pas l'avoir inscrit sur une feuille de route. Plusieurs contrôles portent sur l'honnêteté plutôt que sur la configuration : l'attribution affichée comme déduite, l'analyse incomplète qui ne retire rien, la version de notation sur chaque ligne. Ils valent d'être confirmés, car l'alternative est un rapport qui en promet trop sans le dire.
