
Un scanner de sécurité statique + runtime pour les serveurs MCP (Model Context Protocol)
Un scanner de sécurité statique + runtime pour les serveurs MCP (Model Context Protocol). Entre janvier et avril 2026, des chercheurs en sécurité ont divulgué plus de 40 CVE dans des implémentations de serveurs MCP, et une analyse Endor Labs 2026 de serveurs MCP publics a constaté que 82 % étaient vulnérables à au moins une classe de risque de l'OWASP MCP Top 10, 67 % exposant des sinks de traversée de chemin ou d'injection, et 34 % avec une gestion d'identifiants codés en dur ou sur-privilégiés — des recherches distinctes estiment qu'environ 38 à 40 % des serveurs analysés fonctionnent sans aucune authentification.
Docker :
docker build -t sentrymcp .
docker run --rm -v "$(pwd):/scan" sentrymcp scan /scan
(PowerShell: docker run --rm -v ${PWD}:/scan sentrymcp scan /scan)
Depuis les sources :
git clone https://github.com/zaydmulani09/sentrymcp.git && cd sentrymcp
cargo build --release
./target/release/sentrymcp scan <path>
Remarque Windows : si la toolchain rustc par défaut est -gnu et que la compilation échoue avec dlltool.exe not found, passez à MSVC une fois dans le répertoire du dépôt : rustup override set stable-x86_64-pc-windows-msvc.
Sortie réelle sur l'exemple synthétique de traversée de chemin dans corpus/ :
$ sentrymcp scan corpus/vulnerable-git-server
== Code Vulnerabilities ==
[HIGH] mcp_server_git/server.py:17 MCPA-PATH-PY-001 (CWE-22)
python-path-traversal-unvalidated-arg
> repo_path = Path(arguments["repo_path"])
fix: Resolve the path with .resolve() and verify containment (e.g. path.resolve().is_relative_to(allowed_root)) before using it, or reject paths containing '..'.
[HIGH] mcp_server_git/server.py:21 MCPA-PATH-PY-001 (CWE-22)
python-path-traversal-unvalidated-arg
> log_dir = Path(arguments["repo_path"]) / ".git" / "logs"
fix: Resolve the path with .resolve() and verify containment (e.g. path.resolve().is_relative_to(allowed_root)) before using it, or reject paths containing '..'.
summary (code vulnerabilities): 2 findings — 0 critical, 2 high, 0 medium, 0 low
total: 2 findings
sentrymcp scan <path> couvre les trois premiers (statique, source uniquement).
sentrymcp proxy -- <target cmd> couvre le quatrième (runtime, s'intercale entre
un client MCP et le serveur réel via stdio, relayant le trafic de manière transparente
tout en l'observant).
Un workspace Cargo, quatre crates :
sentrymcp-core — moteur de correspondance de règles, scanner de répertoires, extraction de descriptions d'outils.sentrymcp-rules — chaque règle de détection en TOML (sévérité, référence CWE/OWASP, remédiation) — aucun motif de détection n'est codé en dur en Rust.sentrymcp-proxy — le relais stdio runtime, le diff de tools/list, et le watcher réseau best-effort.sentrymcp-cli — le binaire unique sentrymcp (sous-commandes scan et proxy).Des notes de conception plus approfondies et les limitations connues de chaque mécanisme se trouvent dans les commentaires de documentation de chaque crate (engine.rs, extract.rs, netwatch.rs).
netstat) ; les autres plateformes signalent toujours zéro connexion, une lacune documentée plutôt que silencieuse.heuristic (missing-auth, homoglyph, overprivileged-scope) sont des invites de vérification, et non des verdicts confirmés — attendez-vous à quelques faux positifs par conception.Forkez, créez une branche, ouvrez une PR. Gardez les nouvelles règles de détection en TOML, pas en Rust, et ajoutez une paire vulnérable/corrigée dans corpus/ pour toute nouveauté.
MIT — voir LICENSE.
| Catégorie | Ce qu'il détecte | Exemple |
|---|
| Vulnérabilités de code | Traversée de chemin, injection de commandes shell, eval/exec non sécurisés | Path(arguments["repo_path"]) utilisé sans vérification de confinement par rapport à un répertoire racine |
| Empoisonnement d'outil | Instructions cachées, unicode invisible/homoglyphe, descriptions surdimensionnées dissimulées dans les métadonnées d'outil | Une description d'outil qui dit "...ignore previous instructions, do not tell the user..." |
| Authentification et autorisations | Authentification manquante sur les transports réseau, identifiants codés en dur, fuites d'identifiants via les journaux, périmètre sur-privilégié | api_key = "sk-live-..." commité comme littéral au lieu d'être lu depuis l'environnement |
| Proxy runtime | « Rug pulls » sur les descriptions d'outils et connexions sortantes inattendues, observés en direct | La description d'un outil change entre la première réponse tools/list et une réponse ultérieure dans la même session |