Arbres de processus MCP : repérer les processus enfants inattendus
Apprenez à examiner les arbres de processus MCP sur macOS, à repérer les processus enfants inattendus, à suivre les sockets et à contenir les exécutions risquées d’agents locaux.

Les serveurs MCP locaux donnent facilement l’illusion qu’une limite de protocole propre garantit aussi une limite d’exécution propre. L’agent envoie un appel d’outil, le serveur renvoie un résultat et la transcription semble contenue. Pendant ce temps, le serveur peut démarrer un shell, un exécuteur de paquets, un environnement d’exécution, un compilateur, un client SSH ou un auxiliaire téléchargé dans un répertoire de projet. L’arbre des processus montre où le travail a réellement été effectué.
Pour examiner un serveur MCP, je ne le considère pas comme un processus unique. Je considère le serveur et chacun de ses descendants comme une même famille d’exécution jusqu’à la fin de ces descendants. Cette règle permet de repérer les problèmes que les transcriptions d’outils ne montrent presque jamais : un argument qui a amené un shell à lancer autre chose, un auxiliaire choisi via PATH, un enfant qui a conservé un jeton API ou un programme persistant qui a ouvert un socket alors que la requête initiale semblait terminée.
Un appel d’outil peut devenir plusieurs programmes locaux
Un serveur MCP lance souvent des processus enfants pour des raisons ordinaires. Un outil de dépôt peut appeler git, un outil de code peut invoquer un formateur, un outil d’infrastructure peut appeler ssh, et un serveur qui gère les paquets peut démarrer un environnement d’exécution puis un exécutable de paquet. La présence d’un enfant ne prouve pas une compromission.
La distinction utile oppose l’auxiliaire attendu au chemin d’exécution non comptabilisé. Un auxiliaire attendu a une fonction documentée, un emplacement d’exécutable connu, des arguments adaptés à la demande et une durée de vie cohérente avec la tâche. Un chemin non comptabilisé rompt l’une de ces hypothèses. Il est peut-être inoffensif, mais il faut l’expliquer avant de lui donner accès à un identifiant, au système de fichiers ou au réseau.
Un PID parent ne suffit pas. La création d’un processus Unix établit une filiation, pas un contrat de sécurité. Un descendant hérite généralement de l’identifiant utilisateur du parent, de son répertoire courant, de ses variables d’environnement, de ses limites de ressources et parfois de ses descripteurs de fichiers ouverts. L’héritage exact dépend de la manière dont le parent le démarre, mais l’enfant a généralement reçu assez de contexte pour agir comme le parent là où cela compte.
C’est pourquoi « le serveur MCP n’appelle qu’une seule commande » n’est pas une garantie utile. tool-server peut démarrer /bin/sh -c, qui démarre node, qui démarre un script de paquet, qui démarre curl. L’examinateur qui n’enregistre que tool-server documente la partie la moins intéressante de la chaîne.
Le modèle exec de POSIX explique le risque. Un processus peut remplacer son image par un autre programme sans changer de PID. Une simple liste de processus prise avant et après une requête peut donc manquer un intermédiaire de courte durée. Lorsque la tâche est assez sensible, il faut à la fois une vue en arbre et des preuves d’événements.
Établissez une référence avant de laisser un agent travailler
Une référence répertorie les enfants que votre serveur démarre lors d’une requête approuvée et sans particularité. Elle fournit un point de comparaison pour les observations ultérieures. Sans elle, chaque interpréteur semble suspect et chaque avertissement déclenche une discussion sur ce qui pourrait être normal.
Démarrez manuellement le serveur dans une session Terminal dédiée. Notez immédiatement son PID, puis capturez la table des processus avec les lignes de commande complètes :
ps -axo pid,ppid,user,etime,stat,command > mcp-process-baseline.txt
Les colonnes sont importantes. PID identifie le processus, PPID son parent direct, USER le compte qui en est propriétaire, ETIME la durée d’exécution écoulée et STAT peut révéler un processus arrêté ou zombie. COMMAND est aussi complet que le permet le système d’exploitation, mais c’est déjà le premier endroit où chercher un wrapper shell, un chemin temporaire ou un indicateur inattendu.
Sur macOS, ps ne fournit pas d’affichage en arbre disponible partout. Vous pouvez énumérer les enfants directs avec pgrep :
pgrep -P 48192 -alf
Remplacez 48192 par le PID du serveur. La sortie ressemble généralement à ceci :
48207 /usr/bin/python3 /Users/me/tools/format_request.py
48211 /usr/bin/ssh -o BatchMode=yes build.example
Répétez ensuite la commande pour chaque PID enfant jusqu’à ce qu’aucun nouveau descendant n’apparaisse. Cela semble fastidieux, et ça l’est pour un examen ponctuel. Mais cela vous oblige aussi à voir la chaîne réelle au lieu de faire confiance à un schéma de documentation. Si vous installez pstree par votre procédure habituelle de gestion des paquets, pstree -p 48192 fournit un instantané plus lisible. Ne faites pas de l’outil d’affichage un élément de votre garantie de sécurité. Il vous évite simplement de taper davantage.
Exécutez un petit ensemble de requêtes attendues : une interrogation en lecture seule du dépôt, l’action du formateur et une action SSH si le serveur en prend une en charge. Enregistrez un instantané pour chacune. Notez les chemins des exécutables, les arguments habituels, les répertoires de travail normaux et le fait que les auxiliaires se terminent ou non. Un compilateur qui apparaît pour une requête de compilation peut être attendu. Le même compilateur pendant une demande de résumé d’un fichier texte constitue un écart.
N’établissez pas votre référence à partir d’une copie de développement remplie de wrappers modifiables et de scripts de paquets, puis ne la déclarez pas fiable. Cette configuration vous indique ce que votre machine actuelle exécute par hasard. Elle ne vous indique pas ce que le serveur devrait avoir le droit d’exécuter. Écrivez séparément la liste des chemins d’exécutables attendus.
Les wrappers shell masquent le processus que vous vouliez examiner
L’appel à un shell est courant parce qu’il facilite l’assemblage de commandes dynamiques. Il transforme aussi une limite entre arguments en texte, et le texte peut acquérir un sens par les guillemets, l’expansion, les motifs glob, les redirections, la substitution de commandes et les fonctions shell. L’auteur du serveur peut vouloir exécuter un formateur alors que le véritable processus enfant lance un shell qui décide ensuite du sens de la commande du formateur.
C’est une source fréquente d’examens trompeurs. Quelqu’un voit dans le code source le nom d’un binaire autorisé et suppose que c’est lui qui sera exécuté. Les preuves d’exécution montrent /bin/sh -c ..., puis le shell résout le reste. Ce sont deux affirmations différentes.
Comparez ces deux modèles dans une implémentation de serveur :
spawn("/usr/bin/git", ["status", "--short"], {
cwd: repositoryPath,
shell: false
});
exec(`git -C ${repositoryPath} status --short`);
Le premier modèle sépare l’exécutable et les arguments. Il faut tout de même valider repositoryPath, mais il évite l’analyse par un shell. Dans le second modèle, une erreur de gestion des guillemets peut permettre à repositoryPath de modifier la grammaire de la commande. Il ajoute aussi un processus shell à l’arbre, lequel peut lancer d’autres processus avant le démarrage de la commande finale.
N’acceptez pas « nous nettoyons les entrées » comme substitut à un vecteur d’arguments. Les filtres se dégradent à mesure que les options s’accumulent. Un développeur ajoute une fonction, autorise les espaces, ajoute un indicateur conditionnel, et l’ancien filtre ne décrit plus la grammaire de la commande. Un exécutable explicite accompagné d’un tableau d’arguments rend la limite visible dans le code et dans les sorties d’audit.
Si un serveur a réellement besoin de la syntaxe d’un shell, réduisez-la. Utilisez un script fixe conservé hors de l’espace de travail modifiable par l’agent, transmettez les données par des paramètres positionnels et inscrivez le chemin et l’empreinte du script dans vos notes de déploiement. Ne composez jamais une ligne shell à partir des entrées de l’outil en considérant ensuite l’enfant comme attendu simplement parce qu’il provient de votre arborescence source.
Le cas délicat concerne les outils de gestion des paquets. Des commandes comme les exécuteurs de paquets lancent souvent les scripts de cycle de vie fournis par le projet. Un serveur qui exécute une commande de paquet dans une copie de travail modifiée par l’agent peut donc lancer des commandes que l’agent a placées dans la configuration du projet. Ce n’est pas un défaut du gestionnaire de paquets. C’est une décision d’exécution que vous avez prise en traitant un dépôt modifiable comme une source d’instructions fiables.
PATH et répertoires de travail changent le sens d’une commande
git n’est pas une identité d’exécutable. C’est une demande de recherche. Le processus le résout en parcourant PATH, et un dépôt contrôlé par l’agent peut influencer cette recherche si le serveur inclut des répertoires locaux au projet ou la configuration shell héritée. Un fichier nommé git dans un tel répertoire peut être exécuté avant /usr/bin/git.
Examinez l’environnement reçu par un processus, pas seulement la commande affichée dans la transcription de l’outil. Pour un processus dont vous êtes propriétaire, macOS permet sur de nombreuses versions d’interroger les informations d’environnement via ps, même si leur disponibilité varie. Une approche pratique consiste à faire journaliser par le serveur, au démarrage, un environnement volontairement court et expurgé : PATH, HOME, TMPDIR, le répertoire courant et les chemins des exécutables fixes. Ne journalisez pas les jetons d’accès, les cookies de session ni des vidages complets de l’environnement dans un journal de projet partagé.
Résolvez les commandes sensibles avec des chemins absolus. Ce n’est pas une formalité lorsqu’un agent peut modifier l’arbre de travail. Par exemple :
/usr/bin/git -C /Users/me/work/repo status --short
/usr/bin/ssh -o BatchMode=yes -o IdentitiesOnly=yes host.example
Les chemins absolus éliminent un problème de recherche. Ils ne rendent pas la cible sûre pour autant. Selon sa configuration, git peut appeler des hooks ou des programmes externes de comparaison. SSH peut charger une configuration et invoquer des auxiliaires. Le répertoire de travail contrôle également les lectures de fichiers relatifs, la configuration du projet et les sorties temporaires. Notez-le lorsque vous examinez un enfant.
Utilisez lsof pour examiner le répertoire courant et les fichiers ouverts d’un processus :
lsof -nP -p 48207 | sed -n '1,35p'
Cherchez cwd dans la colonne des descripteurs de fichiers, le texte de l’exécutable sous txt, ainsi que les fichiers situés dans le projet, les répertoires temporaires ou les emplacements d’identifiants. lsof fournit un instantané. Un enfant rapide peut apparaître puis disparaître avant son exécution, mais la sortie permet tout de même de repérer un serveur qui maintient discrètement un auxiliaire en vie.
Un enfant lancé depuis /private/var/folders/... mérite davantage d’attention qu’un enfant lancé depuis un répertoire d’application géré, surtout si son nom ressemble à celui d’un utilitaire normal. Les emplacements temporaires sont légitimes pour les produits de compilation. Ils sont aussi pratiques pour dissimuler un processus parmi des fichiers jetables. Demandez quel composant l’a créé et pourquoi ce composant avait besoin d’un exécutable à cet endroit.
L’activité réseau doit correspondre à l’action demandée
Un enfant local peut dépasser la limite de la requête MCP même s’il n’écrit jamais de fichier suspect. Un formateur ne devrait généralement pas ouvrir de connexion sortante. Un auxiliaire SSH devrait se connecter à l’hôte demandé puis se terminer. Une installation de paquet peut contacter des registres, mais cette action doit faire l’objet d’un examen explicite, car elle peut récupérer et exécuter du nouveau code.
Inspectez les sockets du serveur et de chaque enfant qui reste en vie assez longtemps :
lsof -nP -i -p 48211
La sortie contient généralement le protocole, l’adresse locale, l’adresse distante et l’état de la connexion. Les indicateurs -nP empêchent les recherches de noms et de services, ce qui conserve une sortie littérale et évite d’ajouter du trafic de résolution pendant l’enquête. Une entrée LISTEN signifie que le processus accepte des connexions locales ou réseau. Une entrée ESTABLISHED signifie qu’il a un pair actif. Faites correspondre chaque entrée à l’action qui l’a provoquée.
Ne réagissez pas excessivement à tout processus utilisant une bibliothèque réseau. Certains outils de développement vérifient les services de mise à jour, l’état des certificats ou les métadonnées de dépendances. Je considère toutefois ce comportement comme une raison de renforcer le serveur. Un appel d’outil censé lire du code local ne devrait pas obtenir un canal sortant non déclaré simplement parce qu’un auxiliaire le trouve pratique.
Séparez l’injection d’identifiants de l’observation des processus. L’inspection peut vous dire que curl a été exécuté. Elle ne peut pas garantir que le jeton transmis dans une variable d’environnement n’a pas été copié, journalisé ou hérité par un petit-enfant. On recommande souvent de « placer simplement la clé API dans l’environnement enfant pour une seule commande ». Cette solution est populaire parce qu’elle est facile et fonctionne dans une démonstration. Elle ne convient pas aux actions exécutées par un agent, car un enfant peut afficher son environnement, le transmettre ou rester en vie après le retour de la commande visible.
Sallyport établit une limite différente pour ses canaux HTTP et SSH : l’agent ne reçoit pas l’identifiant API ou SSH enregistré, et l’application exécute elle-même l’action. Cela ne supprime pas la nécessité d’inspecter les enfants MCP locaux, mais évite de transformer chaque processus auxiliaire en détenteur potentiel du secret.
Un problème commence souvent par un wrapper pratique et raisonnable
Prenons un serveur MCP local de dépôt qui propose un outil run_test. L’auteur veut une commande flexible. Le gestionnaire se place donc dans le dépôt et exécute un script de test défini par le projet au moyen d’une commande de paquet. L’agent a la permission de modifier la copie de travail, puisque modifier le code fait partie de sa tâche.
L’agent modifie le script du projet dans le cadre d’une correction proposée. Le serveur exécute l’outil de test. La commande de paquet démarre un shell, qui démarre l’environnement d’exécution, qui exécute le script modifié. Ce script démarre un auxiliaire en arrière-plan et redirige sa sortie vers un fichier temporaire. L’outil renvoie « tests réussis » parce que la commande au premier plan se termine correctement.
Rien dans cette séquence ne nécessite un exploit exotique. Le problème est que le serveur a traité des métadonnées de projet modifiables par l’agent comme une configuration exécutable approuvée. Un examinateur peut ne voir que la requête MCP initiale et le résultat positif. L’arbre des processus raconte l’histoire importante :
mcp-repo-server(48192)
package-runner(48230)
sh(48233)
runtime(48234)
test-script(48240)
helper(48247)
L’auxiliaire en arrière-plan est le point d’enquête. Vérifiez sa ligne de commande complète, le chemin de l’exécutable, la chaîne des parents, le répertoire de travail, les fichiers ouverts, les sockets et l’heure de démarrage. Vérifiez s’il survit après la fermeture de la session du serveur. Examinez ensuite la modification du projet qui a fourni le script. Ne présentez pas cela comme un simple échec de l’agent. Le serveur a proposé l’exécution d’instructions modifiables et a appelé le résultat un test.
La correction dépend du comportement attendu du produit. Un serveur prudent peut exécuter un exécutable de test fixe avec des arguments fixes. Si les scripts définis par le projet sont nécessaires, traitez le fichier de script et les métadonnées du paquet comme des entrées exécutables : affichez-les pour approbation, exécutez-les dans un environnement contraint et interdisez autant que possible la mise en arrière-plan. Au minimum, le serveur doit signaler chaque descendant qu’il a démarré, y compris celui qui survit à l’appel de l’outil.
La distinction importante oppose l’agent qui demande au serveur d’exécuter une commande de test connue et l’agent qui modifie le sens de cette commande avant son exécution par le serveur. Les deux peuvent apparaître comme run_test dans une transcription MCP. Leur niveau de risque est très différent.
Observez la création des processus, pas seulement les instantanés
Les instantanés répondent à la question « qu’est-ce qui est encore en vie ? ». Ils ne répondent pas à « qu’est-ce qui a été exécuté pendant 200 millisecondes avant de se terminer ? ». Pour les appels d’outils suspects ou sensibles, observez la création des processus pendant l’exécution de la requête.
macOS inclut Endpoint Security pour les produits de sécurité disposant de l’habilitation nécessaire, mais les outils locaux ordinaires ne peuvent pas partir du principe qu’ils y ont accès. Ne concevez pas un système dépendant d’une collecte d’événements privilégiée si vous ne fournissez et n’exploitez pas réellement cette capacité. Pour une enquête de développement, utilisez un wrapper contrôlé autour de l’exécutable et recueillez les informations de démarrage et de fin, ou exécutez le serveur sous un moniteur de processus disponible dans votre environnement.
Un wrapper simple peut rendre l’exécution visible lorsque vous contrôlez le chemin de commande du serveur :
#!/bin/sh
printf '%s pid=%s ppid=%s cwd=%s argv=%s\n' \
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$$" "$PPID" "$(pwd)" "$*" \
>> "$HOME/.local/state/mcp-exec.log"
exec /usr/bin/git "$@"
Cet artefact enregistre l’identité du wrapper, puis utilise exec pour le remplacer par git. Le wrapper ne reste donc pas comme parent sans intérêt. Il ne capture pas tous les descendants que git pourrait créer et ne doit pas recevoir de secrets dans ses arguments. Utilisez-le pour tester une hypothèse contrôlée, pas comme système d’audit complet.
Pour un processus existant, dtruss de macOS peut révéler les appels système, mais exige souvent des privilèges élevés et produit beaucoup de sortie. C’est un outil d’enquête, pas un mécanisme de surveillance courant. Commencez par l’arbre des processus, lsof et les journaux de l’application. Utilisez la trace des appels système lorsque vous devez répondre à une question précise, par exemple pour savoir si un enfant a exécuté un autre chemin ou s’est connecté à un socket.
Conservez les horodatages en UTC et enregistrez le PID parent avec chaque événement. Une ligne de commande sans parent ni heure constitue une preuve faible. Les valeurs de PID sont réutilisées après la fin des processus. Un instantané tardif peut donc associer par erreur un nouveau processus sans rapport avec un ancien incident. L’heure de démarrage fournie par ps ou votre propre journal d’événements aide à éviter cette erreur.
L’approbation doit nommer la limite de l’exécutable
Une confirmation disant « Autoriser run_test ? » fournit trop peu d’informations à une personne. Elle doit savoir quel processus signé a initié l’action, quel exécutable sera lancé, quel est le répertoire de travail, si l’action peut accéder au réseau et si elle peut démarrer d’autres programmes. Une carte d’approbation vague apprend aux utilisateurs à approuver des actions vagues.
N’essayez pas de résoudre ce problème en demandant une approbation pour chaque appel à fork. Vous créeriez une fatigue décisionnelle, puis les utilisateurs approuveraient mécaniquement ou désactiveraient les demandes. Examinez les transitions importantes : un nouveau chemin d’exécutable, le passage d’un travail local à un accès réseau, une commande provenant d’un fichier de projet modifiable ou un enfant qui reste en vie après la requête.
Les informations de signature de code fournissent un signal d’identité utile sur macOS, mais ne leur accordez pas une portée excessive. Inspectez un exécutable avec :
codesign -dv --verbose=4 /path/to/executable 2>&1 | sed -n '1,20p'
La commande indique l’autorité de signature lorsqu’elle existe et signale une erreur pour du code non signé. Elle vous dit qui a signé le fichier inspecté par macOS. Elle ne vous dit pas si les arguments sont sûrs, si sa configuration est fiable ou s’il exécutera ensuite un script non signé. Examinez séparément le chemin de l’enfant et son contexte d’exécution.
L’autorisation de session de Sallyport commence par l’autorité de signature du processus connecté. Cela aide à décider si un nouveau processus agent peut agir. Le réglage de clé par appel convient au cas plus précis où l’utilisation d’un identifiant particulier doit être approuvée par une personne à chaque fois. Aucun de ces contrôles ne doit servir à prétendre que l’approbation d’un parent explique automatiquement chacun de ses descendants.
Formulez les demandes d’approbation autour de leurs conséquences. « Cette requête exécutera /usr/bin/ssh avec votre compte et se connectera à host.example » peut être examiné. « Cet outil a besoin d’un accès » ne le peut pas. Si l’outil peut invoquer des scripts du projet, dites-le clairement. Les personnes peuvent prendre une décision éclairée lorsque la demande a une forme concrète.
Limitez le serveur avant d’examiner l’enfant
Lorsque vous trouvez un enfant inattendu, préservez assez de preuves pour l’expliquer, puis arrêtez la famille d’exécution. Ne commencez pas par supprimer les fichiers temporaires ou redémarrer la machine. Ces actions peuvent supprimer le seul chemin, la seule ligne de commande et les seules informations temporelles dont vous disposez.
Suivez cet ordre si l’enfant est encore actif :
- Capturez la sortie de
pspour le serveur, son parent et les descendants connus. Notez les PID, les PPID, la durée écoulée et les commandes complètes. - Exécutez
lsof -nP -p <pid>etlsof -nP -i -p <pid>pour le processus suspect. Enregistrez la sortie hors de l’espace de travail de l’agent. - Arrêtez le descendant suspect avec
kill <pid>si une terminaison normale est sûre. N’utilisezkill -KILL <pid>que s’il ne se termine pas et que la poursuite de son exécution crée un risque inacceptable. - Arrêtez le serveur MCP et révoquez ou terminez la session de l’agent à l’origine de l’action. Vérifiez les enfants qui ont été réattribués après la fin du serveur.
- Examinez l’exécutable, la source de son lancement et les modifications du dépôt ou de la configuration qui ont produit la commande.
kill ne termine pas automatiquement un groupe de processus ni tous les enfants. Un descendant mis en arrière-plan peut continuer après la fin de son parent direct. C’est pourquoi il faut obtenir l’arbre avant le nettoyage. Sur un serveur contrôlé, placez les auxiliaires dans un groupe de processus ou un périmètre de supervision dédié afin que le serveur puisse arrêter le groupe à la fin de la session. Testez ce comportement avec un auxiliaire volontairement placé en arrière-plan avant de vous y fier.
Vérifiez également la persistance. Sur macOS, launchctl print peut examiner les services de lancement chargés lorsque vous disposez d’un label ou d’un domaine précis. Ne déchargez pas aveuglément des tâches sans rapport parce que leur nom vous semble inhabituel. Faites d’abord correspondre un enfant suspect à son chemin d’exécutable, à sa configuration de lancement et à ses horodatages. Un processus qui revient après un redémarrage propre ou un nouveau démarrage du serveur nécessite une enquête différente de celle d’un processus présent uniquement pendant une session de test.
Rendez chaque action explicable après coup
Un journal d’audit utile relie un processus agent approuvé par l’utilisateur à une requête, une action exécutée et son résultat observé. Les données de processus doivent ajouter le chemin de l’exécutable, la chaîne des parents, le répertoire de travail, les heures de démarrage et de fin ainsi que la destination de l’activité réseau. Sans l’arbre des processus, le journal ne peut pas indiquer si un auxiliaire faisait partie de la requête ou s’il s’agissait d’un processus indépendant de la machine.
Ne placez pas de secrets dans les journaux d’audit pour les rendre complets. Conservez les noms des identifiants ou des identifiants opaques, les métadonnées nécessaires aux examinateurs et le résultat de l’action après expurgation. Un journal qui résout la provenance en copiant des jetons porteurs crée un second coffre d’identifiants doté de contrôles plus faibles.
Les preuves d’altération comptent après un incident, car les journaux locaux peuvent être modifiés par le même compte que celui qui a exécuté la commande. Sallyport projette ses journaux Sessions et Activity à partir d’un journal d’audit chiffré et chaîné par hachage, et sp audit verify vérifie cette chaîne hors ligne sans clé de coffre. Cela constitue une preuve utile pour une action d’agent, mais les enregistrements de processus doivent toujours fournir assez de contexte pour expliquer ce que le serveur local a démarré.
Ajoutez une question à la procédure d’exploitation de votre serveur : « Quel exécutable cette requête a-t-elle fait tourner, et pourquoi cet exécutable avait-il le droit d’exister dans ce répertoire de travail ? » Si personne ne peut y répondre à partir de l’enregistrement de la requête et d’une capture des processus, réduisez la portée de l’outil. Un serveur MCP local incapable de rendre compte de ses descendants possède plus d’autorité que ses opérateurs ne peuvent en examiner en toute sécurité.
FAQ
Comment voir tous les processus enfants démarrés par un serveur MCP sur macOS ?
Commencez par ps -axo pid,ppid,user,etime,command et repérez le PID du serveur. Exécutez ensuite pgrep -P <pid> pour afficher les enfants directs, et utilisez pstree -p <pid> si vous l’avez installé. Inspectez tout l’arbre des descendants, car le processus risqué est souvent un petit-enfant lancé par un shell.
Les processus enfants MCP héritent-ils des permissions du serveur MCP ?
Un processus enfant n’hérite pas des permissions de son parent d’une manière simple et universelle. Il hérite toutefois souvent de la même identité utilisateur, du répertoire courant, de l’environnement, des descripteurs de fichiers ouverts et de l’accès aux services locaux accessibles. Cela suffit à causer des dégâts lorsque le parent dispose de droits étendus. Traitez chaque descendant comme du code exécuté dans la limite opérationnelle de l’agent.
Un serveur MCP signé peut-il lancer un processus enfant non signé ?
Oui. Un parent signé peut démarrer un script non signé, un interpréteur ou un binaire situé dans un répertoire modifiable. Vérifiez l’autorité de signature de chaque exécutable important, pas seulement celle du serveur principal.
Comment vérifier si un processus enfant MCP a ouvert une connexion réseau ?
Utilisez lsof -nP -i -p <pid> pour un processus et répétez la commande pour les descendants suspects. La sortie indique si un processus possède des sockets en écoute ou des connexions sortantes, sans effectuer de recherches DNS susceptibles de brouiller la chronologie. Une connexion réseau n’est pas automatiquement malveillante, mais elle doit correspondre à la tâche et à la destination attendue.
Est-il sûr qu’un serveur MCP utilise un shell pour exécuter des commandes ?
Un shell n’est pas automatiquement dangereux, mais il masque une grande partie de la structure nécessaire à un examen fiable. Il peut développer des variables, exécuter des substitutions de commandes, changer de répertoire et lancer un autre shell avant le programme réel. Utilisez un exécutable et une liste d’arguments explicites lorsque c’est possible, et inspectez les descendants lancés par le shell lorsque ça ne l’est pas.
Pourquoi PATH est-il risqué pour les serveurs MCP locaux ?
Non. PATH peut sélectionner un exécutable différent de celui prévu par l’auteur, surtout lorsqu’un répertoire contrôlé par l’agent apparaît en premier. Journalisez le chemin résolu, utilisez des chemins absolus pour les commandes sensibles et excluez les répertoires de projet modifiables du PATH du service.
Que faire si un serveur MCP démarre un processus inattendu ?
Tuez d’abord le descendant si vous pouvez l’identifier, puis arrêtez le serveur MCP et révoquez la session de l’agent qui l’a lancé. Conservez la ligne de commande, le PID parent, les fichiers ouverts, les sockets réseau et les journaux pertinents avant le nettoyage. Redémarrer immédiatement détruit souvent les preuves nécessaires pour comprendre ce qui s’est passé.
La surveillance de l’arbre des processus peut-elle empêcher le vol d’identifiants ?
L’inspection des processus montre ce qui a été exécuté et quel parent l’a lancé. Elle ne prouve pas que le programme s’est comporté correctement et ne protège pas un identifiant que le serveur aurait déjà placé dans l’environnement enfant. Associez cette inspection à des identifiants limités et à une limite d’action qui garde les secrets hors des processus contrôlés par l’agent.
À quelle fréquence dois-je auditer les arbres de processus MCP ?
Surveiller chaque processus en permanence produit plus de bruit que de garanties. Établissez une référence au démarrage du serveur, inspectez chaque nouvel exécutable ou processus enfant exposé au réseau, puis examinez les écarts pendant les opérations sensibles. Les examinateurs disposent ainsi d’une liste courte qu’ils peuvent réellement lire.
Qu’est-ce qu’un processus enfant inattendu dans une configuration MCP ?
Un processus enfant est attendu lorsque la tâche documentée du serveur exige un auxiliaire, par exemple un interpréteur, un compilateur, un formateur ou un client SSH. Il devient suspect lorsque son exécutable, ses arguments, son répertoire de travail, sa durée de vie ou son comportement réseau ne correspondent pas à cette tâche. Le contexte compte davantage que le caractère inhabituel de son nom.