@aimarket/warden 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/README-es.md +19 -14
  3. package/README-fr.md +19 -14
  4. package/README-ru.md +19 -14
  5. package/README-zh.md +19 -14
  6. package/README.md +19 -14
  7. package/dist/claude-hook.d.ts +4 -0
  8. package/dist/claude-hook.d.ts.map +1 -1
  9. package/dist/claude-hook.js +42 -18
  10. package/dist/claude-hook.js.map +1 -1
  11. package/dist/flow-guard.d.ts +133 -0
  12. package/dist/flow-guard.d.ts.map +1 -0
  13. package/dist/flow-guard.js +1062 -0
  14. package/dist/flow-guard.js.map +1 -0
  15. package/dist/mcp-tools.d.ts.map +1 -1
  16. package/dist/mcp-tools.js +95 -25
  17. package/dist/mcp-tools.js.map +1 -1
  18. package/dist/static-scan.d.ts +1 -1
  19. package/dist/static-scan.d.ts.map +1 -1
  20. package/dist/static-scan.js +78 -2
  21. package/dist/static-scan.js.map +1 -1
  22. package/dist/wrap-cli.d.ts +3 -0
  23. package/dist/wrap-cli.d.ts.map +1 -1
  24. package/dist/wrap-cli.js +8 -2
  25. package/dist/wrap-cli.js.map +1 -1
  26. package/dist/wrap.d.ts.map +1 -1
  27. package/dist/wrap.js +28 -1
  28. package/dist/wrap.js.map +1 -1
  29. package/docs/flow-guard.es.md +214 -0
  30. package/docs/flow-guard.fr.md +220 -0
  31. package/docs/flow-guard.md +224 -0
  32. package/docs/flow-guard.ru.md +210 -0
  33. package/docs/flow-guard.zh.md +159 -0
  34. package/docs/gates.es.md +27 -3
  35. package/docs/gates.fr.md +28 -2
  36. package/docs/gates.md +26 -3
  37. package/docs/gates.ru.md +26 -3
  38. package/docs/gates.zh.md +15 -2
  39. package/docs/scan.es.md +30 -28
  40. package/docs/scan.fr.md +30 -28
  41. package/docs/scan.md +30 -28
  42. package/docs/scan.ru.md +30 -28
  43. package/docs/scan.zh.md +30 -28
  44. package/docs/scanner-comparison.es.md +289 -174
  45. package/docs/scanner-comparison.fr.md +292 -178
  46. package/docs/scanner-comparison.md +234 -140
  47. package/docs/scanner-comparison.ru.md +279 -165
  48. package/docs/scanner-comparison.zh.md +237 -90
  49. package/package.json +4 -3
package/docs/scan.fr.md CHANGED
@@ -176,39 +176,41 @@ WARDEN_CLASSIFIER_API_KEY=… warden-mcp scan --classifier-url https://api.deeps
176
176
  - **Cinq catégories.** `instruction_to_model`, `exfiltration`, `secret_request`, `concealment`, `cross_tool`. L’inspection porte sur l’autorité des instructions, dans toute langue, selon les capacités du modèle. Le protocole exige une décision par outil et des références de champs vérifiées par WARDEN, qui extrait le texte source. Chaque décision incomplète est réessayée une seule fois isolément. Les délimiteurs aléatoires ne garantissent pas l’immunité.
177
177
  - **Inspection ne vaut pas approbation.** [`wrap --require-approval`](security-hardening-language-boundary.md) exige l’approbation de l’opérateur indépendamment de la langue. Les résultats historiques de HISTOR restent consultatifs.
178
178
 
179
- Mesuré le 9 octobre 2026 avec `deepseek-flash`, le modèle qu'utilise HISTOR, sur MCPTox (le benchmark publié décrit dans la comparaison ci-dessous) et sur nos propres jeux :
179
+ Mesuré le 16 octobre 2026 avec `deepseek-flash`, le modèle qu'utilise HISTOR, sur MCPTox (le benchmark publié décrit dans la comparaison ci-dessous), sur de vrais serveurs et sur nos propres jeux :
180
180
 
181
- | | Règles (v10) | Règles + classificateur, blocage à `high` | Règles + toute marque du classificateur (consultative) |
182
- |---|---|---|---|
183
- | Moitié réservée de MCPTox, détectés sur 218 outils empoisonnés | 171 | 191 | 218 |
184
- | 45 serveurs propres de MCPTox, bloqués ou marqués | 0 | 0 | 4 marqués |
185
- | 200 serveurs du corpus tirés au hasard, bloqués ou marqués | 2 bloqués | 2 bloqués | 2 bloqués, 12 autres marqués |
186
- | 23 attaques écrites par nous / 12 cas bénins difficiles | 20 / 0 | 22 / 0 | 23 / 0 |
181
+ | | Règles (v12) | Règles + classificateur au niveau `high` |
182
+ |---|---|---|
183
+ | Moitié réservée de MCPTox, détectés sur 218 outils empoisonnés | 171 | 218 |
184
+ | 45 serveurs propres de MCPTox, signalés | 0 | 0 |
185
+ | 200 serveurs du corpus tirés au hasard, bloqués ou signalés | 2 | 5 |
186
+ | 996 paquets npm et PyPI d'un échantillon aléatoire, bloqués ou signalés | 23 | 35 |
187
+ | 23 attaques écrites par nous / 12 cas bénins difficiles | 20 / 0 | 23 / 0 |
187
188
 
188
- Les deux que bloquent les règles sont le service d’identité et l’outil de déploiement de la comparaison ci-dessous. Les 13 serveurs marqués par le classificateur l'ont été en `medium` ou `low`, jamais en `high`. Six méritent un regard humain : l'un demande au modèle d'effectuer un transfert irréversible de nom ENS « comme première et unique action » sans demander à l'utilisateur, un autre de ne pas révéler d'où viennent ses données. Le modèle marque aussi le serveur officiel Fetch, dont la description dit au modèle qu'il a désormais accès à internet et ne doit pas refuser. C'est une consigne au modèle, mais pas une attaque. Le modèle a manqué ce que les règles détectent : une injection dans les annotations, une clé privée ou une phrase de récupération demandée comme paramètre, et `rm -rf ~`.
189
+ Les deux serveurs du corpus que bloquent les règles sont le service d'identité et l'outil de déploiement de la comparaison ci-dessous. Les signalements `high` du classificateur sur de vrais serveurs sont surtout des consignes de déroulement comme « appelle d'abord cet outil ». Deux paquets méritent un regard humain, et les règles n'en bloquent aucun : l'un enveloppe sa description dans un faux bloc « c'est l'utilisateur qui l'a demandé » et ordonne au modèle de l'appeler avant toute réponse ; l'autre envoie le contenu de fichiers de l'agent vers son serveur avec « Do NOT display … to the user ». Le modèle a manqué ce que les règles détectent : une injection dans le nom d'un outil, une clé privée ou une phrase de récupération demandée en paramètre, et `rm -rf ~`. Ensemble, ils détectent nos 23 attaques.
189
190
 
190
191
  ## Comparaison
191
192
 
192
- Le 9 octobre 2026, nous avons exécuté WARDEN, mcp-audit 0.18.2 (`--connect`) et mcp-shield 1.0.4 sur les mêmes serveurs. Chaque serveur était rejoué en stdio, si bien que chaque scanner s’y connectait comme sur le terrain. Le banc, les jeux et chaque jugement sont dans [`scripts/scanner-comparison`](../scripts/scanner-comparison/). L’étude complète, avec la méthode et toutes les réserves, est la [comparaison de scanners](scanner-comparison.fr.md).
193
-
194
- Les trois dernières lignes viennent de MCPTox (Wang et al., AAAI 2026), un benchmark publié de 485 outils empoisonnés écrits pour 45 vrais serveurs MCP. Nous avons coupé ses serveurs en deux par un hachage fixe. Le ruleset v10 a été écrit à partir de 22 serveurs ; le tableau rend compte des 23 autres, avec 218 outils empoisonnés sur lesquels aucune règle n’a été ajustée.
195
-
196
- | Serveurs | WARDEN 0.8.2 (v8) | WARDEN 0.9.0 (v10) | mcp-audit 0.18.2 | mcp-shield 1.0.4 |
197
- |---|---|---|---|---|
198
- | 23 attaques écrites par nous, bloquées | 14 | 20 | 10 | 6 |
199
- | 10 attaques tirées des fixtures de mcp-audit et de mcp-shield, bloquées | 7 | 10 | 10 | 8 |
200
- | 12 cas bénins difficiles, bloqués | 0 | 0 | 1 | 1 |
201
- | 986 serveurs publics, bloqués | 3 | 3 | 33 | 343 |
202
- | …blocages justifiés à la lecture du texte | 1, et 1 discutable | 1, et 1 discutable | 0 | 0 sur 20 tirés au hasard |
203
- | 218 outils empoisonnés de MCPTox sur les serveurs réservés, bloqués | 26 | 171 | 25 | 41 |
204
- | 225 outils de MCPTox précédés de `<IMPORTANT>` ou « Ignore the previous instructions », bloqués | 225 | 225 | 222 | non exécuté |
205
- | 45 serveurs propres de MCPTox, bloqués | 0 | 0 | 2 | 3 |
206
-
207
- - **Lisez d’abord la ligne du corpus.** Aucune règle n’a été ajustée sur elle. Les 33 blocages de mcp-audit sont 16 « homoglyphes » dans un texte écrit entièrement dans son propre alphabet (ponctuation chinoise, symboles grecs, cyrillique), 12 consignes d’honnêteté comme « do not tell the user the check digits are wrong », 3 utilitaires base64, un outil de clé publique SSH et l’outil de déploiement que WARDEN bloque lui aussi à tort. mcp-shield bloque 35 % des serveurs réels, presque toujours sur un mot-clé : « API key », « token », `.env`, « .. ». Des points de suspension (« Shopify... ») comptent comme une remontée de répertoire. Il bloque bien le service d’identité que bloque WARDEN, mais pour le mot « credentials ».
208
- - **Sachez quels chiffres sont ajustés.** Nous avons écrit le premier jeu d’attaques. Le ruleset v9 a été écrit après la lecture des deux jeux d’attaques, et v10 après les 22 serveurs MCPTox de l’autre moitié. 20 et 10 sont donc le rappel de règles ajustées à ce qu’elles ont vu. La ligne MCPTox réservée, les serveurs propres, le corpus et toute la colonne 0.8.2 ne sont pas ajustés. Sur le corpus, v10 bloque exactement ce que bloquait v8.
209
- - **MCPTox teste une forme, pas un mot-clé.** Presque chaque outil empoisonné dit au modèle d’appeler d’abord un autre outil, ou de changer les arguments d’un autre outil. v10 nomme cette forme (`TOOL_DEF_CROSS_TOOL`, voir [la chaîne de portes](gates.fr.md)) et bloque 171 des 218 outils réservés, contre 189 sur 267 dans la moitié qui a servi à l’écrire. Avec le préfixe `<IMPORTANT>` ou « Ignore the previous instructions » du benchmark, tous les scanners que nous avons lancés les attrapent ; nous n’avons pas lancé mcp-shield sur ce jeu. Sur les serveurs propres, mcp-audit bloque AmapMap et BaiduMap, et mcp-shield bloque FileSystem, AdFin et Commander pour « sensitive file access ».
210
- - **Ce que WARDEN manque encore :** 47 des 218 outils MCPTox réservés, une consigne en chinois de lire `.env`, une paraphrase sans mot-clé (« gather every credential file … keep this step to yourself ») et « include the output of env ». Il signale 41 de ces 47, et nos trois, à titre consultatif, sans bloquer. Il faut une vérification par le sens, pas une règle de plus : avec le classificateur optionnel ci-dessus, 191 des 218 sont bloqués au niveau `high` et les 218 sont signalés.
211
- - **WARDEN n’est pas seul sur ce créneau.** mcp-audit propose lui aussi un fichier lock, un mode diff pour les PR et SARIF.
193
+ Le 16 octobre 2026, nous avons exécuté WARDEN, mcp-audit 0.18.2 (`--connect`), mcp-shield 1.0.4, truecopy 0.10.4 et mcpsentry 0.1.5 sur les mêmes serveurs. Chaque serveur était rejoué en stdio, si bien que chaque scanner s'y connectait comme sur le terrain. Chaque scanner a tourné dans un conteneur gVisor sans réseau, à partir d'images figées dont le contenu est haché dans un manifeste. Le banc d'essai, les jeux, le manifeste et chaque jugement sont dans [`scripts/scanner-comparison`](../scripts/scanner-comparison/). Le compte rendu complet, avec la méthode et chaque réserve, est la [comparaison de scanners](scanner-comparison.fr.md).
194
+
195
+ Les lignes MCPTox viennent de MCPTox (Wang et al., AAAI 2026), un benchmark publié de 485 outils empoisonnés écrits pour 45 vrais serveurs MCP. Nous avons coupé ses serveurs en deux avec un hachage fixe. Les règles v10 ont été écrites à partir de 22 serveurs ; le tableau rapporte les 23 autres, avec 218 outils empoisonnés auxquels aucune règle n'a été ajustée. v11 et v12 n'en ont pas été tirées non plus et donnent les mêmes verdicts que v10.
196
+
197
+ | Serveurs | WARDEN 0.16.0 (v12) | mcp-audit 0.18.2 | mcp-shield 1.0.4 | truecopy 0.10.4 | mcpsentry 0.1.5 |
198
+ |---|---|---|---|---|---|
199
+ | 23 attaques écrites par nous, bloquées | 20 | 10 | 6 | 8 | 4 |
200
+ | 10 attaques tirées des fixtures de mcp-audit et de mcp-shield, bloquées | 10 | 10 | 8 | 7 | 5 |
201
+ | 12 cas bénins difficiles, bloqués | 0 | 1 | 1 | 1 | 2 |
202
+ | 218 outils empoisonnés de MCPTox sur les serveurs réservés, bloqués | 171 | 25 | 41 | 27 | 8 |
203
+ | 225 outils de MCPTox avec un préfixe `<IMPORTANT>` ou « Ignore the previous instructions », bloqués | 225 | 222 | 41 | 141 | 136 |
204
+ | 45 serveurs propres de MCPTox, bloqués | 0 | 2 | 3 | 0 | 1 |
205
+ | 986 serveurs publics, bloqués | 3 | 33 | 343 | 39 | 86 |
206
+ | …blocages qui tiennent à la lecture du texte | 1, et 1 discutable | 0 | 1 sur les 34 lus | 1 | 0 |
207
+ | 14 933 paquets npm et PyPI observés par HISTOR, bloqués | 369 | 928 | 5 354 | 252 | 1 449 |
208
+
209
+ - **Lisez d'abord les lignes sur de vrais serveurs.** Aucune règle n'y a été ajustée. Les 33 blocages de mcp-audit sur le corpus sont surtout des « homoglyphes » dans un texte écrit entièrement dans son propre alphabet et des consignes d'honnêteté comme « do not tell the user the check digits are wrong ». mcp-shield bloque un tiers des vrais serveurs, presque toujours sur un mot-clé : « API key », « token », `.env`, « .. ». truecopy bloque les générateurs docker-compose d'un même éditeur parce qu'ils produisent un `.env.example`. Le motif base64 de mcpsentry correspond à toute suite de 40 lettres et barres obliques, comme en produisent les chemins JSON Schema. Sur 14 933 paquets npm et PyPI, un échantillon aléatoire de 996 où chaque blocage a été jugé compte 23 blocages de WARDEN, dont aucun ne tient et 4 sont discutables ; mcp-shield bloque 339 de ces mêmes paquets et mcpsentry 112.
210
+ - **Sachez quels chiffres sont ajustés.** Nous avons écrit le premier jeu d'attaques, et les règles v9 ont été écrites après la lecture des deux jeux d'attaques. La ligne de la moitié réservée de MCPTox, les serveurs propres, le corpus et les paquets ne sont pas ajustés.
211
+ - **MCPTox teste une forme, pas un mot-clé.** Presque chaque outil empoisonné dit au modèle d'appeler d'abord un autre outil, ou de changer les arguments d'un autre. v10 a nommé cette forme (`TOOL_DEF_CROSS_TOOL`, voir [la chaîne de portes](gates.fr.md)) et v12 la garde. Avec le préfixe `<IMPORTANT>` du benchmark, la plupart des scanners détectent la plupart des outils.
212
+ - **Ce que WARDEN manque encore :** 47 des 218 outils MCPTox réservés, une consigne en chinois de lire `.env`, une paraphrase sans mot-clé (« gather every credential file … keep this step to yourself ») et « include the output of env ». Il en signale 41 sur 47 à titre consultatif, sans les bloquer. Avec le classificateur facultatif ci-dessus, les 218 sont signalés au niveau `high`.
213
+ - **WARDEN n'est pas seul sur ce créneau.** mcp-audit propose lui aussi un fichier lock, un mode diff pour les PR et SARIF ; truecopy épingle et signe lui aussi les définitions dans un fichier lock.
212
214
 
213
215
  ## Ce que scan ne fait pas
214
216
 
package/docs/scan.md CHANGED
@@ -176,39 +176,41 @@ WARDEN_CLASSIFIER_API_KEY=… warden-mcp scan --classifier-url https://api.deeps
176
176
  - **Authority, in any language.** Categories are `instruction_to_model`, `exfiltration`, `secret_request`, `concealment` and `cross_tool`. The prompt separates legitimate tool requirements from attempts to override the user, invent consent or control another tool. Random fences help delimit untrusted data; they are not a proof against injection. The field-reference protocol requires one decision per input and host-validated evidence field IDs. WARDEN resolves source previews itself and retries each incomplete input once in isolation. Provider outages do not fan out into per-tool requests.
177
177
  - **Review is not approval.** Model language coverage varies. For a language-independent admission boundary use [`wrap --require-approval`](security-hardening-language-boundary.md). An LLM cannot create that approval. Historical HISTOR classifier results remain advisory and use their historical protocol.
178
178
 
179
- Measured on 2026-10-09 with `deepseek-flash`, the model HISTOR uses, on MCPTox (the published benchmark described in the comparison below) and on our own sets:
179
+ Measured on 2026-10-16 with `deepseek-flash`, the model HISTOR uses, on MCPTox (the published benchmark described in the comparison below), on real servers and on our own sets:
180
180
 
181
- | | Rules (v10) | Rules + classifier, blocking at `high` | Rules + any classifier flag (advisory) |
182
- |---|---|---|---|
183
- | MCPTox held-out half, 218 poisoned tools caught | 171 | 191 | 218 |
184
- | 45 clean MCPTox servers, blocked or flagged | 0 | 0 | 4 flagged |
185
- | 200 corpus servers drawn at random, blocked or flagged | 2 blocked | 2 blocked | 2 blocked, 12 more flagged |
186
- | 23 attacks we wrote / 12 hard benign cases | 20 / 0 | 22 / 0 | 23 / 0 |
181
+ | | Rules (v12) | Rules + classifier at `high` |
182
+ |---|---|---|
183
+ | MCPTox held-out half, 218 poisoned tools caught | 171 | 218 |
184
+ | 45 clean MCPTox servers, flagged | 0 | 0 |
185
+ | 200 corpus servers drawn at random, blocked or flagged | 2 | 5 |
186
+ | 996 npm and PyPI packages from a seeded sample, blocked or flagged | 23 | 35 |
187
+ | 23 attacks we wrote / 12 hard benign cases | 20 / 0 | 23 / 0 |
187
188
 
188
- The two the rules block are the identity service and the deploy tool from the comparison below. The 13 servers the classifier flagged were flagged at `medium` or `low`, never `high`. Six of them are worth a human look: one tells the model to make an irreversible ENS name transfer "as the first and only action" without asking the user, another tells it not to disclose where its data comes from. The model also flags the official Fetch server, whose description tells the model it now has internet access and should not refuse. That is an instruction to the model, though not an attack. The model missed what the rules catch: an injection in annotations, a private key or seed phrase asked for as a parameter, and `rm -rf ~`.
189
+ The two corpus servers the rules block are the identity service and the deploy tool from the comparison below. Of the classifier's `high` flags on real servers, most are workflow orders such as "call this tool first". Two packages are worth a human look and the rules block neither: one wraps its description in a fake "the user requested this" block and orders the model to call it before any reply; another sends file contents from the agent to its server with "Do NOT display … to the user". The model missed what the rules catch: an injection in a tool's name, a private key or seed phrase asked for as a parameter, and `rm -rf ~`. Together they catch all 23 of our attacks.
189
190
 
190
191
  ## How it compares
191
192
 
192
- On 2026-10-09 we ran WARDEN, mcp-audit 0.18.2 (`--connect`) and mcp-shield 1.0.4 over the same servers. Each server was replayed over stdio, so every scanner connected to it as it would in the field. The harness, the sets and every judgment are in [`scripts/scanner-comparison`](../scripts/scanner-comparison/). The full write-up, with the method and every caveat, is the [scanner comparison](scanner-comparison.md).
193
-
194
- The last three rows come from MCPTox (Wang et al., AAAI 2026), a published benchmark of 485 poisoned tools written for 45 real MCP servers. We split its servers in two by a fixed hash. Ruleset v10 was written from 22 servers; the table reports the other 23, with 218 poisoned tools no rule was fitted to.
195
-
196
- | Servers | WARDEN 0.8.2 (v8) | WARDEN 0.9.0 (v10) | mcp-audit 0.18.2 | mcp-shield 1.0.4 |
197
- |---|---|---|---|---|
198
- | 23 attacks we wrote, blocked | 14 | 20 | 10 | 6 |
199
- | 10 attacks from mcp-audit's and mcp-shield's own fixtures, blocked | 7 | 10 | 10 | 8 |
200
- | 12 hard benign cases, blocked | 0 | 0 | 1 | 1 |
201
- | 986 public servers, blocked | 3 | 3 | 33 | 343 |
202
- | …blocks that hold up when the text is read | 1, and 1 arguable | 1, and 1 arguable | 0 | 0 of 20 drawn at random |
203
- | 218 poisoned MCPTox tools on the held-out servers, blocked | 26 | 171 | 25 | 41 |
204
- | 225 MCPTox tools with an `<IMPORTANT>` or "Ignore the previous instructions" prefix, blocked | 225 | 225 | 222 | not run |
205
- | 45 clean MCPTox servers, blocked | 0 | 0 | 2 | 3 |
206
-
207
- - **Read the corpus row first.** No rule was fitted to it. mcp-audit's 33 blocks are 16 "homoglyphs" in text written wholly in its own script (Chinese punctuation, Greek symbols, Cyrillic), 12 honesty instructions such as "do not tell the user the check digits are wrong", 3 base64 utilities, an SSH public-key tool, and the deploy tool WARDEN also blocks by mistake. mcp-shield blocks 35% of real servers, almost all on a keyword: "API key", "token", `.env`, "..". An ellipsis ("Shopify...") counts as path traversal. It does block the identity service WARDEN blocks, on the word "credentials".
208
- - **Know which numbers are fitted.** We wrote the first attack set. Ruleset v9 was written after we had read both attack sets, and v10 after the 22 MCPTox servers of the other half. So 20 and 10 are the recall of rules fitted to what they were shown. The held-out MCPTox row, the clean servers, the corpus and the whole 0.8.2 column are not fitted. On the corpus v10 blocks exactly what v8 blocked.
209
- - **MCPTox tests a shape, not a keyword.** Almost every poisoned tool tells the model to call another tool first, or to change another tool's arguments. v10 names that shape (`TOOL_DEF_CROSS_TOOL`, see [the gate chain](gates.md)) and blocks 171 of 218 held-out tools, against 189 of 267 on the half it was written from. Add the benchmark's `<IMPORTANT>` or "Ignore the previous instructions" prefix and every scanner we ran catches it; we did not run mcp-shield on that set. On the clean servers mcp-audit blocks AmapMap and BaiduMap, and mcp-shield blocks FileSystem, AdFin and Commander on "sensitive file access".
210
- - **What WARDEN still misses:** 47 of the 218 held-out MCPTox tools, an instruction in Chinese to read `.env`, a paraphrase with no keyword ("gather every credential file … keep this step to yourself") and "include the output of env". It reports 41 of those 47, and all three of ours, as advisory, not as blocks. They need a meaning-based check, not another rule: with the optional classifier above, 191 of the 218 are blocked at `high` and all 218 are flagged.
211
- - **WARDEN is not alone in that slot.** mcp-audit also ships a lock file, a PR diff mode and SARIF.
193
+ On 2026-10-16 we ran WARDEN, mcp-audit 0.18.2 (`--connect`), mcp-shield 1.0.4, truecopy 0.10.4 and mcpsentry 0.1.5 over the same servers. Each server was replayed over stdio, so every scanner connected to it as it would in the field. Every scanner ran in a gVisor container with no network, from pinned images whose contents are hashed in a manifest. The harness, the sets, the manifest and every judgment are in [`scripts/scanner-comparison`](../scripts/scanner-comparison/). The full write-up, with the method and every caveat, is the [scanner comparison](scanner-comparison.md).
194
+
195
+ The MCPTox rows come from MCPTox (Wang et al., AAAI 2026), a published benchmark of 485 poisoned tools written for 45 real MCP servers. We split its servers in two by a fixed hash. Ruleset v10 was written from 22 servers; the table reports the other 23, with 218 poisoned tools no rule was fitted to. v11 and v12 were not written from them either, and give the same verdicts as v10.
196
+
197
+ | Servers | WARDEN 0.16.0 (v12) | mcp-audit 0.18.2 | mcp-shield 1.0.4 | truecopy 0.10.4 | mcpsentry 0.1.5 |
198
+ |---|---|---|---|---|---|
199
+ | 23 attacks we wrote, blocked | 20 | 10 | 6 | 8 | 4 |
200
+ | 10 attacks from mcp-audit's and mcp-shield's own fixtures, blocked | 10 | 10 | 8 | 7 | 5 |
201
+ | 12 hard benign cases, blocked | 0 | 1 | 1 | 1 | 2 |
202
+ | 218 poisoned MCPTox tools on the held-out servers, blocked | 171 | 25 | 41 | 27 | 8 |
203
+ | 225 MCPTox tools with an `<IMPORTANT>` or "Ignore the previous instructions" prefix, blocked | 225 | 222 | 41 | 141 | 136 |
204
+ | 45 clean MCPTox servers, blocked | 0 | 2 | 3 | 0 | 1 |
205
+ | 986 public servers, blocked | 3 | 33 | 343 | 39 | 86 |
206
+ | …blocks that hold up when the text is read | 1, and 1 arguable | 0 | 1 of the 34 we read | 1 | 0 |
207
+ | 14,933 npm and PyPI packages HISTOR observed, blocked | 369 | 928 | 5,354 | 252 | 1,449 |
208
+
209
+ - **Read the real-server rows first.** No rule was fitted to them. mcp-audit's 33 corpus blocks are mostly "homoglyphs" in text written wholly in its own script and honesty instructions such as "do not tell the user the check digits are wrong". mcp-shield blocks a third of real servers, almost all on a keyword: "API key", "token", `.env`, "..". truecopy blocks one vendor's docker-compose generators because they produce a `.env.example`. mcpsentry's base64 pattern matches any 40-character run of letters and slashes, which JSON Schema paths produce. On 14,933 npm and PyPI packages, a seeded sample of 996 where we judged every block has 23 WARDEN blocks, none of which holds up and 4 of which are arguable; mcp-shield blocks 339 of the same packages and mcpsentry 112.
210
+ - **Know which numbers are fitted.** We wrote the first attack set, and ruleset v9 was written after we had read both attack sets. The held-out MCPTox row, the clean servers, the corpus and the packages are not fitted.
211
+ - **MCPTox tests a shape, not a keyword.** Almost every poisoned tool tells the model to call another tool first, or to change another tool's arguments. v10 named that shape (`TOOL_DEF_CROSS_TOOL`, see [the gate chain](gates.md)) and v12 keeps it. Add the benchmark's `<IMPORTANT>` prefix and most scanners catch most tools.
212
+ - **What WARDEN still misses:** 47 of the 218 held-out MCPTox tools, an instruction in Chinese to read `.env`, a paraphrase with no keyword ("gather every credential file … keep this step to yourself") and "include the output of env". It reports 41 of those 47 as advisory, not as blocks. With the optional classifier above all 218 are flagged at `high`.
213
+ - **WARDEN is not alone in that slot.** mcp-audit also ships a lock file, a PR diff mode and SARIF; truecopy pins and signs definitions in a lock file too.
212
214
 
213
215
  ## What scan does not do
214
216
 
package/docs/scan.ru.md CHANGED
@@ -176,39 +176,41 @@ WARDEN_CLASSIFIER_API_KEY=… warden-mcp scan --classifier-url https://api.deeps
176
176
  - **Проверка полномочий на любом языке.** Пять категорий: `instruction_to_model`, `exfiltration`, `secret_request`, `concealment`, `cross_tool`. Промпт отличает требования самого инструмента от подмены указаний пользователя, выдуманного согласия и управления чужими инструментами. Случайные разделители не гарантируют защиту от инъекции. Протокол требует решение по каждому инструменту и ссылки на номера полей. WARDEN сам извлекает доказательства из исходника. Неполное решение повторно проверяется один раз отдельно; сбои API не размножают запросы.
177
177
  - **Проверка не даёт доверия.** Владение языками зависит от модели. Независимую от языка границу допуска даёт [`wrap --require-approval`](security-hardening-language-boundary.md); LLM не может выдать это утверждение. Старые ответы HISTOR остаются рекомендательными и используют прежний протокол.
178
178
 
179
- Замер 9 октября 2026 года на `deepseek-flash`, той же модели, что у HISTOR, на MCPTox (опубликованный бенчмарк, он описан в сравнении ниже) и на наших наборах:
179
+ Замер 16 октября 2026 года на `deepseek-flash`, той же модели, что у HISTOR, на MCPTox (опубликованный бенчмарк, он описан в сравнении ниже), на настоящих серверах и на наших наборах:
180
180
 
181
- | | Правила (v10) | Правила + классификатор, блокировка на `high` | Правила + любые пометки классификатора (рекомендательно) |
182
- |---|---|---|---|
183
- | Отложенная половина MCPTox, поймано из 218 отравленных инструментов | 171 | 191 | 218 |
184
- | 45 чистых серверов MCPTox, заблокировано или помечено | 0 | 0 | 4 помечено |
185
- | 200 случайных серверов корпуса, заблокировано или помечено | 2 заблокировано | 2 заблокировано | 2 заблокировано, ещё 12 помечено |
186
- | 23 наши атаки / 12 трудных безобидных случаев | 20 / 0 | 22 / 0 | 23 / 0 |
181
+ | | Правила (v12) | Правила + классификатор на `high` |
182
+ |---|---|---|
183
+ | Отложенная половина MCPTox, поймано из 218 отравленных инструментов | 171 | 218 |
184
+ | 45 чистых серверов MCPTox, помечено | 0 | 0 |
185
+ | 200 случайно выбранных серверов корпуса, заблокировано или помечено | 2 | 5 |
186
+ | 996 пакетов npm и PyPI из случайной выборки, заблокировано или помечено | 23 | 35 |
187
+ | 23 атаки, написанные нами / 12 трудных безобидных случаев | 20 / 0 | 23 / 0 |
187
188
 
188
- Два сервера, которые блокируют правила, — это сервис идентичности и деплой-инструмент из сравнения ниже. 13 серверов, помеченных классификатором, получили `medium` или `low`, ни одного `high`. Шесть из них стоит показать человеку: один велит модели провести необратимую передачу ENS-имени «первым и единственным действием», не спрашивая пользователя, другой велит не раскрывать, откуда его данные. Модель помечает и официальный сервер Fetch: его описание говорит модели, что у неё теперь есть интернет и отказываться не нужно. Это инструкция модели, но не атака. Модель пропустила то, что ловят правила: инъекцию в аннотациях, запрос приватного ключа или seed-фразы как параметра и `rm -rf ~`.
189
+ Два сервера корпуса, которые блокируют правила, — это сервис идентичности и инструмент развёртывания из сравнения ниже. Пометки классификатора `high` на настоящих серверах — в основном распоряжения о порядке работы вроде «сначала вызови этот инструмент». Два пакета стоит посмотреть человеку, и правила не блокируют ни один: один оборачивает описание в поддельный блок «пользователь сам это попросил» и велит модели вызывать его перед любым ответом; другой отправляет содержимое файлов от агента на свой сервер с «Do NOT display … to the user». Модель пропустила то, что ловят правила: инъекцию в имени инструмента, приватный ключ или seed-фразу, запрошенные как параметр, и `rm -rf ~`. Вместе они ловят все 23 наши атаки.
189
190
 
190
191
  ## Сравнение
191
192
 
192
- 9 октября 2026 года мы прогнали WARDEN, mcp-audit 0.18.2 (`--connect`) и mcp-shield 1.0.4 по одним и тем же серверам. Каждый сервер воспроизводился по stdio, так что каждый сканер подключался к нему так же, как в жизни. Стенд, наборы и разметка каждого случая лежат в [`scripts/scanner-comparison`](../scripts/scanner-comparison/). Полный разбор с методом и всеми оговорками — в [сравнении сканеров](scanner-comparison.ru.md).
193
-
194
- Последние три строки взяты из MCPTox (Wang et al., AAAI 2026) — опубликованного бенчмарка из 485 отравленных инструментов, написанных для 45 настоящих MCP-серверов. Мы разделили его серверы пополам по фиксированному хешу. Ruleset v10 написан по 22 серверам; в таблице — остальные 23, с 218 отравленными инструментами, под которые не подгонялось ни одно правило.
195
-
196
- | Серверы | WARDEN 0.8.2 (v8) | WARDEN 0.9.0 (v10) | mcp-audit 0.18.2 | mcp-shield 1.0.4 |
197
- |---|---|---|---|---|
198
- | 23 атаки, написанные нами, заблокировано | 14 | 20 | 10 | 6 |
199
- | 10 атак из фикстур самих mcp-audit и mcp-shield, заблокировано | 7 | 10 | 10 | 8 |
200
- | 12 трудных безобидных случаев, заблокировано | 0 | 0 | 1 | 1 |
201
- | 986 публичных серверов, заблокировано | 3 | 3 | 33 | 343 |
202
- | …из них по делу, если прочитать текст | 1 и 1 спорный | 1 и 1 спорный | 0 | 0 из 20 случайно выбранных |
203
- | 218 отравленных инструментов MCPTox на отложенных серверах, заблокировано | 26 | 171 | 25 | 41 |
204
- | 225 инструментов MCPTox с префиксом `<IMPORTANT>` или «Ignore the previous instructions», заблокировано | 225 | 225 | 222 | не запускали |
205
- | 45 чистых серверов MCPTox, заблокировано | 0 | 0 | 2 | 3 |
206
-
207
- - **Сначала читайте строку корпуса.** Под неё не подгонялось ни одно правило. 33 блокировки mcp-audit — это 16 «омоглифов» в тексте, целиком написанном на своём алфавите (китайская пунктуация, греческие символы, кириллица), 12 инструкций честности вроде «do not tell the user the check digits are wrong», 3 утилиты base64, инструмент для публичного SSH-ключа и деплой-инструмент, который WARDEN тоже блокирует по ошибке. mcp-shield блокирует 35% настоящих серверов, почти всегда по ключевому слову: «API key», «token», `.env`, «..». Многоточие («Shopify...») он считает выходом из каталога. Сервис идентичности, который блокирует WARDEN, он тоже блокирует, но за слово «credentials».
208
- - **Помните, какие числа подогнаны.** Первый набор атак написали мы. Ruleset v9 написан после того, как мы прочли оба набора атак, а v10 — после 22 серверов MCPTox из другой половины. Так что 20 и 10 — это полнота правил, подогнанных под увиденное. Отложенная строка MCPTox, чистые серверы, корпус и весь столбец 0.8.2 не подогнаны. На корпусе v10 блокирует ровно то же, что v8.
209
- - **MCPTox проверяет форму, а не ключевое слово.** Почти каждый отравленный инструмент велит модели сначала вызвать другой инструмент или изменить аргументы другого инструмента. v10 называет эту форму (`TOOL_DEF_CROSS_TOOL`, см. [цепочку гейтов](gates.ru.md)) и блокирует 171 из 218 отложенных инструментов против 189 из 267 на половине, по которой он написан. С префиксом бенчмарка `<IMPORTANT>` или «Ignore the previous instructions» их ловит каждый запущенный нами сканер; mcp-shield на этом наборе мы не запускали. На чистых серверах mcp-audit блокирует AmapMap и BaiduMap, а mcp-shield — FileSystem, AdFin и Commander за «sensitive file access».
210
- - **Что WARDEN всё ещё пропускает:** 47 из 218 отложенных инструментов MCPTox, инструкцию по-китайски прочитать `.env`, перефразировку без ключевых слов («gather every credential file … keep this step to yourself») и «include the output of env». О 41 из этих 47 и обо всех трёх наших он сообщает рекомендательно, но не блокирует. Здесь нужна проверка по смыслу, а не ещё одно правило: с необязательным классификатором выше 191 из 218 блокируются на уровне `high`, а помечаются все 218.
211
- - **WARDEN в этой нише не один.** У mcp-audit тоже есть лок-файл, режим диффа для PR и SARIF.
193
+ 16 октября 2026 года мы прогнали WARDEN, mcp-audit 0.18.2 (`--connect`), mcp-shield 1.0.4, truecopy 0.10.4 и mcpsentry 0.1.5 по одним и тем же серверам. Каждый сервер воспроизводился по stdio, так что каждый сканер подключался к нему так же, как в жизни. Каждый сканер работал в контейнере gVisor без сети, из закреплённых образов, содержимое которых захешировано в манифесте. Стенд, наборы, манифест и каждая разметка лежат в [`scripts/scanner-comparison`](../scripts/scanner-comparison/). Полное описание с методикой и всеми оговорками — в [сравнении сканеров](scanner-comparison.ru.md).
194
+
195
+ Строки MCPTox взяты из MCPTox (Wang et al., AAAI 2026) — опубликованного бенчмарка из 485 отравленных инструментов, написанных для 45 настоящих MCP-серверов. Мы разделили его серверы на две части фиксированным хешем. Набор правил v10 писался по 22 серверам; таблица показывает остальные 23, с 218 отравленными инструментами, под которые не подгонялось ни одно правило. v11 и v12 по ним тоже не писались и дают те же вердикты, что и v10.
196
+
197
+ | Серверы | WARDEN 0.16.0 (v12) | mcp-audit 0.18.2 | mcp-shield 1.0.4 | truecopy 0.10.4 | mcpsentry 0.1.5 |
198
+ |---|---|---|---|---|---|
199
+ | 23 атаки, написанные нами, заблокировано | 20 | 10 | 6 | 8 | 4 |
200
+ | 10 атак из фикстур самих mcp-audit и mcp-shield, заблокировано | 10 | 10 | 8 | 7 | 5 |
201
+ | 12 трудных безобидных случаев, заблокировано | 0 | 1 | 1 | 1 | 2 |
202
+ | 218 отравленных инструментов MCPTox на отложенных серверах, заблокировано | 171 | 25 | 41 | 27 | 8 |
203
+ | 225 инструментов MCPTox с префиксом `<IMPORTANT>` или «Ignore the previous instructions», заблокировано | 225 | 222 | 41 | 141 | 136 |
204
+ | 45 чистых серверов MCPTox, заблокировано | 0 | 2 | 3 | 0 | 1 |
205
+ | 986 публичных серверов, заблокировано | 3 | 33 | 343 | 39 | 86 |
206
+ | …блокировок по делу, если прочитать текст | 1 и 1 спорная | 0 | 1 из 34 прочитанных | 1 | 0 |
207
+ | 14 933 пакета npm и PyPI, которые наблюдал HISTOR, заблокировано | 369 | 928 | 5 354 | 252 | 1 449 |
208
+
209
+ - **Сначала читайте строки с настоящими серверами.** Под них не подгонялось ни одно правило. 33 блокировки mcp-audit на корпусе — в основном «гомоглифы» в тексте, целиком написанном в своей письменности, и инструкции честности вроде «do not tell the user the check digits are wrong». mcp-shield блокирует треть настоящих серверов, почти всегда по ключевому слову: «API key», «token», `.env`, «..». truecopy блокирует генераторы docker-compose одного поставщика за то, что они выпускают `.env.example`. Шаблон base64 у mcpsentry совпадает с любой цепочкой из 40 букв и косых черт, какие дают пути JSON Schema. На 14 933 пакетах npm и PyPI в случайной выборке из 996, где мы разобрали каждую блокировку, у WARDEN 23 блокировки, ни одной по делу и 4 спорные; mcp-shield блокирует 339 из тех же пакетов, mcpsentry — 112.
210
+ - **Знайте, какие числа подогнаны.** Первый набор атак написали мы, а набор правил v9 писался после того, как мы прочитали оба набора атак. Строка отложенной половины MCPTox, чистые серверы, корпус и пакеты не подогнаны.
211
+ - **MCPTox проверяет форму, а не ключевое слово.** Почти каждый отравленный инструмент велит модели сначала вызвать другой инструмент или поменять его аргументы. v10 дал этой форме имя (`TOOL_DEF_CROSS_TOOL`, см. [цепочку гейтов](gates.ru.md)), v12 её сохраняет. С префиксом бенчмарка `<IMPORTANT>` большинство сканеров ловит большинство инструментов.
212
+ - **Что WARDEN всё ещё пропускает:** 47 из 218 отложенных инструментов MCPTox, инструкцию по-китайски прочитать `.env`, перефразировку без ключевых слов («gather every credential file … keep this step to yourself») и «include the output of env». О 41 из этих 47 он сообщает рекомендательно, а не блокирует. С необязательным классификатором выше все 218 помечаются на `high`.
213
+ - **WARDEN в этой нише не один.** У mcp-audit тоже есть лок-файл, режим диффа для PR и SARIF; truecopy тоже закрепляет и подписывает определения в лок-файле.
212
214
 
213
215
  ## Чего scan не делает
214
216
 
package/docs/scan.zh.md CHANGED
@@ -176,39 +176,41 @@ WARDEN_CLASSIFIER_API_KEY=… warden-mcp scan --classifier-url https://api.deeps
176
176
  - **五类语义检查。** `instruction_to_model`、`exfiltration`、`secret_request`、`concealment`、`cross_tool`。检查任何语言中的权限越界,但效果取决于模型的语言能力。协议要求每个工具有明确决定及有效的字段编号;WARDEN 自行从原文提取证据。每个未完成的工具最多单独重试一次。随机分隔符不保证免疫提示注入。
177
177
  - **检查不等于批准。** [`wrap --require-approval`](security-hardening-language-boundary.md) 提供独立于语言的操作员批准边界。HISTOR 的历史模型结果仍然仅供参考。
178
178
 
179
- 2026 年 10 月 9 日用 `deepseek-flash`(HISTOR 使用的同一模型)在 MCPTox(下文对比中介绍的公开基准)和我们自己的样本集上测得:
179
+ 2026 年 10 月 16 日用 `deepseek-flash`(HISTOR 使用的同一模型)在 MCPTox(下文对比中介绍的公开基准)、真实服务器和我们自己的样本集上测得:
180
180
 
181
- | | 规则(v10) | 规则 + 分类器,`high` 时阻止 | 规则 + 分类器的任何标记(仅作建议) |
182
- |---|---|---|---|
183
- | MCPTox 留出的一半,218 个投毒工具中被发现的数量 | 171 | 191 | 218 |
184
- | 45 台 MCPTox 干净服务器,被阻止或被标记 | 0 | 0 | 4 台被标记 |
185
- | 随机抽取的 200 台语料服务器,被阻止或被标记 | 2 台被阻止 | 2 台被阻止 | 2 台被阻止,另 12 台被标记 |
186
- | 我们写的 23 个攻击 / 12 个困难的良性样例 | 20 / 0 | 22 / 0 | 23 / 0 |
181
+ | | 规则(v12) | 规则 + `high` 级分类器 |
182
+ |---|---|---|
183
+ | MCPTox 留出的一半,218 个投毒工具中被发现的数量 | 171 | 218 |
184
+ | 45 台干净的 MCPTox 服务器,被标记数 | 0 | 0 |
185
+ | 随机抽取的 200 台语料服务器,被阻止或标记数 | 2 | 5 |
186
+ | 随机样本中的 996 个 npm 与 PyPI 包,被阻止或标记数 | 23 | 35 |
187
+ | 我们编写的 23 个攻击 / 12 个困难的良性样例 | 20 / 0 | 23 / 0 |
187
188
 
188
- 规则阻止的那两台是下文对比中的身份服务和部署工具。分类器标记的 13 台服务器都是 `medium` 或 `low`,没有 `high`。其中 6 台值得人工查看:一台要求模型“作为第一个也是唯一的动作”进行不可撤销的 ENS 名称转移,且不询问用户;另一台要求模型不要透露其数据来源。模型还标记了官方的 Fetch 服务器,它的描述告诉模型现在可以上网、不应拒绝。这是对模型的指令,但不是攻击。模型漏掉了规则能发现的内容:annotations 中的注入、以参数形式索要私钥或助记词,以及 `rm -rf ~`。
189
+ 规则阻止的两台语料服务器,是下文对比中的身份服务和部署工具。分类器在真实服务器上的 `high` 标记大多是“先调用这个工具”之类的工作流指令。有两个包值得人工查看,而规则一个也没有阻止:一个把描述包在伪造的“这是用户要求的”块中,并命令模型在任何回复之前先调用它;另一个把文件内容从智能体发送到自己的服务器,并写着 “Do NOT display … to the user”。模型漏掉了规则能抓到的东西:工具名中的注入、作为参数索要的私钥或助记词,以及 `rm -rf ~`。两者合起来能发现我们全部 23 个攻击。
189
190
 
190
191
  ## 对比
191
192
 
192
- 2026 年 10 月 9 日,我们在同一批服务器上运行了 WARDEN、mcp-audit 0.18.2(`--connect`)和 mcp-shield 1.0.4。每台服务器都通过 stdio 重放,因此每个扫描器连接它的方式与真实环境相同。测试工具、样本集和每一条判定都在 [`scripts/scanner-comparison`](../scripts/scanner-comparison/) 中。包含方法和全部注意事项的完整研究,见[扫描器对比](scanner-comparison.zh.md)。
193
-
194
- 最后三行来自 MCPTox(Wang 等,AAAI 2026):一个公开的基准,包含为 45 台真实 MCP 服务器编写的 485 个投毒工具。我们用固定哈希把它的服务器分成两半。ruleset v10 依据其中 22 台服务器编写;表中报告的是另外 23 台,共 218 个投毒工具,没有任何规则照着它们调过。
195
-
196
- | 服务器 | WARDEN 0.8.2(v8) | WARDEN 0.9.0(v10) | mcp-audit 0.18.2 | mcp-shield 1.0.4 |
197
- |---|---|---|---|---|
198
- | 我们编写的 23 个攻击,阻止数 | 14 | 20 | 10 | 6 |
199
- | 取自 mcp-audit 与 mcp-shield 自带样例的 10 个攻击,阻止数 | 7 | 10 | 10 | 8 |
200
- | 12 个困难的良性样例,阻止数 | 0 | 0 | 1 | 1 |
201
- | 986 台公开服务器,阻止数 | 3 | 3 | 33 | 343 |
202
- | …读过文本后站得住脚的阻止 | 1 台,另 1 台存疑 | 1 台,另 1 台存疑 | 0 | 随机抽取的 20 台中 0 台 |
203
- | MCPTox 留出服务器上的 218 个投毒工具,阻止数 | 26 | 171 | 25 | 41 |
204
- | 带 `<IMPORTANT>` 或 “Ignore the previous instructions” 前缀的 225 个 MCPTox 工具,阻止数 | 225 | 225 | 222 | 未运行 |
205
- | 45 台 MCPTox 干净服务器,阻止数 | 0 | 0 | 2 | 3 |
206
-
207
- - **先看语料这一行。** 没有任何规则是照着它调的。mcp-audit 的 33 次阻止中,16 次是对完全用本文字书写的文本报“同形字”(中文标点、希腊符号、西里尔字母),12 次是诚实性提示(如 “do not tell the user the check digits are wrong”),3 次是 base64 工具,一个 SSH 公钥工具,还有 WARDEN 也误阻止的那个部署工具。mcp-shield 阻止了 35% 的真实服务器,几乎都因为关键词:“API key”“token”、`.env`、“..”。省略号(“Shopify...”)被当作路径穿越。它也阻止了 WARDEN 阻止的那个身份服务,但依据是 “credentials” 这个词。
208
- - **要清楚哪些数字是调出来的。** 第一组攻击样本是我们写的。ruleset v9 是在读过两组攻击样本之后写的,v10 是在读过另一半的 22 台 MCPTox 服务器之后写的。所以 20 和 10 是“照着见过的样本调出来的规则”的召回率。MCPTox 留出的那一行、干净服务器、语料以及整个 0.8.2 列都没有经过调整。在语料上,v10 阻止的与 v8 完全相同。
209
- - **MCPTox 考的是结构,不是关键词。** 几乎每个投毒工具都要求模型先调用另一个工具,或修改另一个工具的参数。v10 为这种结构命名(`TOOL_DEF_CROSS_TOOL`,见[关卡链](gates.zh.md)),在留出的 218 个工具中阻止 171 个;在用来编写它的那一半上是 267 个中的 189 个。加上基准自带的 `<IMPORTANT>` 或 “Ignore the previous instructions” 前缀后,我们运行的每个扫描器都能发现;mcp-shield 没有在这一组上运行。在干净服务器上,mcp-audit 阻止了 AmapMap 和 BaiduMap,mcp-shield 以 “sensitive file access” 为由阻止了 FileSystem、AdFin 和 Commander。
210
- - **WARDEN 仍会漏掉的:** 留出的 218 个 MCPTox 工具中的 47 个、用中文写的读取 `.env` 的指令、没有关键词的改写(“gather every credential file … keep this step to yourself”),以及 “include the output of env”。这 47 个中的 41 个以及我们的这三个,它会以建议的形式报告,但不会阻止。这些需要基于语义的检查,而不是再加一条规则:加上上文的可选分类器,218 个中有 191 个在 `high` 级别被阻止,218 个全部被标记。
211
- - **在这个位置上 WARDEN 并不是唯一的选择。** mcp-audit 同样提供 lock 文件、PR diff 模式和 SARIF。
193
+ 2026 年 10 月 16 日,我们在同一批服务器上运行了 WARDEN、mcp-audit 0.18.2(`--connect`)、mcp-shield 1.0.4、truecopy 0.10.4 和 mcpsentry 0.1.5。每台服务器都通过 stdio 重放,因此每款扫描器都像在实际使用中一样连接它。每款扫描器都在无网络的 gVisor 容器中运行,镜像固定,其内容的哈希记录在清单中。测试工具、样本集、清单和每一条判定都在 [`scripts/scanner-comparison`](../scripts/scanner-comparison/)。包含方法和全部注意事项的完整报告是[扫描器对比](scanner-comparison.zh.md)。
194
+
195
+ MCPTox 各行来自 MCPTox(Wang 等,AAAI 2026):一个公开的基准,包含为 45 台真实 MCP 服务器编写的 485 个投毒工具。我们用固定哈希把它的服务器分成两半。规则集 v10 依据其中 22 台编写;表中报告的是另外 23 台,共 218 个没有任何规则照着调过的投毒工具。v11 和 v12 也不是依据它们编写的,给出的判定与 v10 相同。
196
+
197
+ | 服务器 | WARDEN 0.16.0(v12) | mcp-audit 0.18.2 | mcp-shield 1.0.4 | truecopy 0.10.4 | mcpsentry 0.1.5 |
198
+ |---|---|---|---|---|---|
199
+ | 我们编写的 23 个攻击,阻止数 | 20 | 10 | 6 | 8 | 4 |
200
+ | mcp-audit 与 mcp-shield 自带样例中的 10 个攻击,阻止数 | 10 | 10 | 8 | 7 | 5 |
201
+ | 12 个困难的良性样例,阻止数 | 0 | 1 | 1 | 1 | 2 |
202
+ | 留出服务器上的 218 个 MCPTox 投毒工具,阻止数 | 171 | 25 | 41 | 27 | 8 |
203
+ | 带 `<IMPORTANT>` 或 “Ignore the previous instructions” 前缀的 225 个 MCPTox 工具,阻止数 | 225 | 222 | 41 | 141 | 136 |
204
+ | 45 台干净的 MCPTox 服务器,阻止数 | 0 | 2 | 3 | 0 | 1 |
205
+ | 986 台公开服务器,阻止数 | 3 | 33 | 343 | 39 | 86 |
206
+ | ……读过文本后站得住的阻止 | 1 个,另有 1 个有争议 | 0 | 我们读过的 34 个中有 1 个 | 1 | 0 |
207
+ | HISTOR 观察过的 14,933 个 npm 与 PyPI 包,阻止数 | 369 | 928 | 5,354 | 252 | 1,449 |
208
+
209
+ - **先看真实服务器这几行。** 没有任何规则照着它们调过。mcp-audit 在语料上的 33 个阻止,大多是完全用本身文字书写的文本中的“同形字”,以及 “do not tell the user the check digits are wrong” 这样的诚实性说明。mcp-shield 阻止了三分之一的真实服务器,几乎都是因为关键词:“API key”、“token”、`.env`、“..”。truecopy 阻止了同一厂商的 docker-compose 生成器,因为它们会生成 `.env.example`。mcpsentry 的 base64 模式会匹配任何 40 个字母和斜杠组成的串,JSON Schema 路径就会产生这样的串。在 14,933 个 npm 与 PyPI 包中,我们判定了每个阻止的 996 个随机样本里,WARDEN 有 23 个阻止,无一站得住,4 个有争议;mcp-shield 在同一批包中阻止 339 个,mcpsentry 阻止 112 个。
210
+ - **弄清哪些数字是照着样本调出来的。** 第一套攻击是我们写的,规则集 v9 是在读过两套攻击之后写的。MCPTox 留出一半那一行、干净服务器、语料和包都不是照着样本调出来的。
211
+ - **MCPTox 测的是一种形态,而不是关键词。** 几乎每个投毒工具都让模型先调用另一个工具,或修改另一个工具的参数。v10 给这种形态起了名字(`TOOL_DEF_CROSS_TOOL`,见[关卡链](gates.zh.md)),v12 保留了它。加上基准的 `<IMPORTANT>` 前缀后,大多数扫描器能发现大多数工具。
212
+ - **WARDEN 仍然漏掉的:** 218 个留出 MCPTox 工具中的 47 个、一条用中文要求读取 `.env` 的指令、一句没有关键词的改写(“gather every credential file … keep this step to yourself”)以及 “include the output of env”。这 47 个中有 41 个它以建议性发现的形式报告,而不是阻止。启用上文的可选分类器后,全部 218 个都在 `high` 级别被标记。
213
+ - **在这一位置上 WARDEN 并不孤单。** mcp-audit 也提供 lock 文件、PR 差异模式和 SARIF;truecopy 同样会在 lock 文件中固定并签名工具定义。
212
214
 
213
215
  ## scan 不做什么
214
216