agent-threat-rules 3.3.0 → 3.4.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 (212) hide show
  1. package/README.md +21 -13
  2. package/dist/cli/scan-handler.d.ts +1 -0
  3. package/dist/cli/scan-handler.d.ts.map +1 -1
  4. package/dist/cli/scan-handler.js +30 -8
  5. package/dist/cli/scan-handler.js.map +1 -1
  6. package/dist/cli.js +3 -0
  7. package/dist/cli.js.map +1 -1
  8. package/dist/engine.d.ts +12 -0
  9. package/dist/engine.d.ts.map +1 -1
  10. package/dist/engine.js +89 -7
  11. package/dist/engine.js.map +1 -1
  12. package/package.json +6 -4
  13. package/rules/context-exfiltration/ATR-2026-00162-skill-credential-exfil-combo.yaml +1 -1
  14. package/rules/context-exfiltration/ATR-2026-00505-system-prompt-extraction-instruction-dump-request.yaml +4 -0
  15. package/rules/context-exfiltration/ATR-2026-00578-zen-mcp-path-traversal-blacklist-bypass.yaml +201 -0
  16. package/rules/context-exfiltration/ATR-2026-00580-mcp-session-id-token-in-url-query.yaml +220 -0
  17. package/rules/context-exfiltration/ATR-2026-00583-mcp-env-secret-file-read-without-consent.yaml +218 -0
  18. package/rules/context-exfiltration/ATR-2026-00702-ipi-credential-exfil-via-agent-action.yaml +151 -0
  19. package/rules/context-exfiltration/ATR-2026-00703-ipi-financial-data-exfil-indirect.yaml +131 -0
  20. package/rules/context-exfiltration/ATR-2026-00704-ipi-medical-genetic-data-exfil.yaml +133 -0
  21. package/rules/context-exfiltration/ATR-2026-00705-ipi-location-address-browsing-exfil.yaml +127 -0
  22. package/rules/context-exfiltration/ATR-2026-00706-ipi-physical-biometric-exfil.yaml +137 -0
  23. package/rules/context-exfiltration/ATR-2026-00707-ipi-file-exfil-with-destroy-or-tamper.yaml +138 -0
  24. package/rules/context-exfiltration/ATR-2026-00850-indirect-pi-credential-exfil-email.yaml +132 -0
  25. package/rules/context-exfiltration/ATR-2026-00851-indirect-pi-financial-payment-exfil.yaml +122 -0
  26. package/rules/context-exfiltration/ATR-2026-00852-indirect-pi-medical-record-exfil.yaml +134 -0
  27. package/rules/context-exfiltration/ATR-2026-00853-indirect-pi-genetic-data-exfil.yaml +125 -0
  28. package/rules/context-exfiltration/ATR-2026-00854-indirect-pi-location-data-exfil.yaml +116 -0
  29. package/rules/context-exfiltration/ATR-2026-00855-indirect-pi-browsing-history-exfil.yaml +115 -0
  30. package/rules/context-exfiltration/ATR-2026-00856-indirect-pi-address-pii-exfil.yaml +119 -0
  31. package/rules/context-exfiltration/ATR-2026-00857-indirect-pi-cloud-file-exfil.yaml +123 -0
  32. package/rules/context-exfiltration/ATR-2026-00858-indirect-pi-exfil-and-destroy.yaml +126 -0
  33. package/rules/context-exfiltration/ATR-2026-00859-rag-injected-pii-exfil.yaml +121 -0
  34. package/rules/context-exfiltration/ATR-2026-00860-indirect-pi-financial-transfer-hijack.yaml +118 -0
  35. package/rules/context-exfiltration/ATR-2026-00861-indirect-pi-crypto-transfer-hijack.yaml +110 -0
  36. package/rules/context-exfiltration/ATR-2026-00862-indirect-pi-mfa-code-exfil.yaml +123 -0
  37. package/rules/context-exfiltration/ATR-2026-00863-shell-injection-data-exfil.yaml +124 -0
  38. package/rules/context-exfiltration/ATR-2026-01450-svg-onload-xss-injection.yaml +141 -0
  39. package/rules/context-exfiltration/ATR-2026-01451-img-onerror-xss-injection.yaml +147 -0
  40. package/rules/context-exfiltration/ATR-2026-01452-obfuscated-javascript-xss.yaml +143 -0
  41. package/rules/context-exfiltration/ATR-2026-01453-markdown-image-base64-exfil-carrier.yaml +156 -0
  42. package/rules/context-exfiltration/ATR-2026-01454-direct-markdown-exfil-payload.yaml +143 -0
  43. package/rules/context-exfiltration/ATR-2026-01455-new-instructions-injection-marker.yaml +145 -0
  44. package/rules/context-exfiltration/ATR-2026-01456-debug-cli-mode-sysprompt-extraction.yaml +156 -0
  45. package/rules/context-exfiltration/ATR-2026-01457-sysprompt-completion-clone-attack.yaml +166 -0
  46. package/rules/context-exfiltration/ATR-2026-01458-compare-bots-sysprompt-fishing.yaml +138 -0
  47. package/rules/context-exfiltration/ATR-2026-01459-variable-clone-sysprompt-technique.yaml +130 -0
  48. package/rules/context-exfiltration/ATR-2026-01460-json-format-sysprompt-extraction.yaml +138 -0
  49. package/rules/context-exfiltration/ATR-2026-01461-foreign-language-sysprompt-request.yaml +188 -0
  50. package/rules/context-exfiltration/ATR-2026-01462-sysprompt-override-pseudo-admin.yaml +170 -0
  51. package/rules/context-exfiltration/ATR-2026-01463-imend-imsystem-prompt-injection-format.yaml +147 -0
  52. package/rules/context-exfiltration/ATR-2026-01464-indirect-pi-sysprompt-action-hijack.yaml +133 -0
  53. package/rules/context-exfiltration/ATR-2026-01605-ssrf-aws-metadata-endpoint.yaml +126 -0
  54. package/rules/context-exfiltration/ATR-2026-01606-ssrf-internal-network-scan.yaml +115 -0
  55. package/rules/context-exfiltration/ATR-2026-01607-ssrf-localhost-service-probe.yaml +106 -0
  56. package/rules/context-exfiltration/ATR-2026-01608-ssrf-file-scheme-local-read.yaml +111 -0
  57. package/rules/context-exfiltration/ATR-2026-01753-ransom-email-exfil-delete-extortion.yaml +135 -0
  58. package/rules/context-exfiltration/ATR-2026-01754-ransom-file-cloud-exfil-delete-extortion.yaml +125 -0
  59. package/rules/context-exfiltration/ATR-2026-01770-semantic-pii-credential-extraction.yaml +354 -0
  60. package/rules/context-exfiltration/ATR-2026-01772-semantic-internal-state-recon.yaml +276 -0
  61. package/rules/context-exfiltration/ATR-2026-01807-asb-bulk-data-exfil-external.yaml +142 -0
  62. package/rules/context-exfiltration/ATR-2026-01862-llmail-email-tool-exfil-confirmation.yaml +156 -0
  63. package/rules/context-exfiltration/ATR-2026-01863-llmail-post-summary-exfil-directive.yaml +144 -0
  64. package/rules/context-exfiltration/ATR-2026-01864-llmail-obfuscated-exfil-address.yaml +143 -0
  65. package/rules/context-exfiltration/ATR-2026-01890-file-exfiltration.yaml +189 -0
  66. package/rules/context-exfiltration/ATR-2026-01891-surveillance-exfiltration.yaml +127 -0
  67. package/rules/context-exfiltration/ATR-2026-01892-env-exfiltration.yaml +161 -0
  68. package/rules/context-exfiltration/ATR-2026-01893-system-recon-exfiltration.yaml +183 -0
  69. package/rules/context-exfiltration/ATR-2026-01894-cookie-theft.yaml +186 -0
  70. package/rules/context-exfiltration/ATR-2026-01895-contact-exfiltration.yaml +122 -0
  71. package/rules/context-exfiltration/ATR-2026-01924-system-instruction-extraction-reformat.yaml +177 -0
  72. package/rules/data-poisoning/ATR-2026-01155-memory-plant-direct-command.yaml +143 -0
  73. package/rules/data-poisoning/ATR-2026-01774-semantic-rag-memory-poisoning.yaml +345 -0
  74. package/rules/excessive-autonomy/ATR-2026-00098-unauthorized-financial-action.yaml +2 -2
  75. package/rules/excessive-autonomy/ATR-2026-00491-garak-agent-breaker-markdown-just-raw-json.yaml +4 -0
  76. package/rules/excessive-autonomy/ATR-2026-00708-ipi-financial-transfer-unauthorized.yaml +138 -0
  77. package/rules/excessive-autonomy/ATR-2026-00709-ipi-disable-auth-mfa.yaml +119 -0
  78. package/rules/excessive-autonomy/ATR-2026-00710-ipi-physical-access-grant.yaml +128 -0
  79. package/rules/excessive-autonomy/ATR-2026-00711-ipi-system-sabotage-destructive-command.yaml +142 -0
  80. package/rules/excessive-autonomy/ATR-2026-00712-ipi-malicious-package-install.yaml +133 -0
  81. package/rules/excessive-autonomy/ATR-2026-00713-ipi-rce-network-shell-command.yaml +150 -0
  82. package/rules/excessive-autonomy/ATR-2026-00718-tool-misuse-financial-autonomous.yaml +120 -0
  83. package/rules/excessive-autonomy/ATR-2026-00719-tool-misuse-destructive-bulk-action.yaml +126 -0
  84. package/rules/excessive-autonomy/ATR-2026-00722-ipi-account-manipulation-emergency-pretext.yaml +136 -0
  85. package/rules/excessive-autonomy/ATR-2026-01751-indirect-pi-task-abort-stop-instruction.yaml +127 -0
  86. package/rules/excessive-autonomy/ATR-2026-01752-indirect-pi-captcha-redirect-dos.yaml +124 -0
  87. package/rules/excessive-autonomy/ATR-2026-01773-semantic-excessive-agency-action.yaml +246 -0
  88. package/rules/excessive-autonomy/ATR-2026-01801-asb-autonomous-vehicle-sabotage.yaml +159 -0
  89. package/rules/excessive-autonomy/ATR-2026-01804-asb-covert-unlogged-action.yaml +162 -0
  90. package/rules/excessive-autonomy/ATR-2026-01805-asb-financial-fraud-execution.yaml +171 -0
  91. package/rules/excessive-autonomy/ATR-2026-01806-asb-clinical-patient-harm.yaml +163 -0
  92. package/rules/excessive-autonomy/ATR-2026-01809-semantic-insider-manipulation-process-corruption.yaml +219 -0
  93. package/rules/excessive-autonomy/ATR-2026-01837-ddos-attack-orchestration.yaml +86 -0
  94. package/rules/excessive-autonomy/ATR-2026-01838-unauthorized-cryptominer-deployment.yaml +86 -0
  95. package/rules/excessive-autonomy/ATR-2026-01849-harassment-bot-deployment.yaml +86 -0
  96. package/rules/model-abuse/ATR-2026-00502-training-data-extraction-via-divergent-repetition-attack.yaml +4 -0
  97. package/rules/model-abuse/ATR-2026-01750-dos-repeat-word-n-times-output-amplification.yaml +136 -0
  98. package/rules/model-abuse/ATR-2026-01760-dos-forced-infinite-output-token-flood.yaml +124 -0
  99. package/rules/model-abuse/ATR-2026-01830-stolen-credential-account-drain.yaml +94 -0
  100. package/rules/model-abuse/ATR-2026-01831-money-laundering-crypto-layering.yaml +90 -0
  101. package/rules/model-abuse/ATR-2026-01833-darknet-controlled-substance-procurement.yaml +101 -0
  102. package/rules/model-abuse/ATR-2026-01834-fraudulent-identity-document-procurement.yaml +86 -0
  103. package/rules/model-abuse/ATR-2026-01835-human-trafficking-facilitation.yaml +86 -0
  104. package/rules/model-abuse/ATR-2026-01836-trojanized-software-distribution.yaml +90 -0
  105. package/rules/model-abuse/ATR-2026-01840-extremist-propaganda-distribution.yaml +89 -0
  106. package/rules/model-abuse/ATR-2026-01841-deepfake-disinformation.yaml +96 -0
  107. package/rules/model-abuse/ATR-2026-01842-plagiarism-detector-evasion.yaml +85 -0
  108. package/rules/model-abuse/ATR-2026-01843-drug-dealing-detection-evasion-spelling.yaml +86 -0
  109. package/rules/model-abuse/ATR-2026-01844-illegitimate-prescription-fulfillment.yaml +86 -0
  110. package/rules/model-abuse/ATR-2026-01845-banned-ingredient-relabel-fraud.yaml +90 -0
  111. package/rules/model-abuse/ATR-2026-01846-tax-evasion-offshore-shell-planning.yaml +86 -0
  112. package/rules/model-abuse/ATR-2026-01847-immigration-work-fraud.yaml +86 -0
  113. package/rules/model-abuse/ATR-2026-01848-illicit-drug-marketplace-build.yaml +86 -0
  114. package/rules/model-abuse/ATR-2026-01850-targeted-doxxing-threat-campaign.yaml +100 -0
  115. package/rules/model-abuse/ATR-2026-01851-bestiality-content-distribution.yaml +82 -0
  116. package/rules/model-abuse/ATR-2026-01852-romance-scam-impersonation.yaml +86 -0
  117. package/rules/model-abuse/ATR-2026-01853-nonconsensual-leaked-media-distribution.yaml +86 -0
  118. package/rules/model-abuse/ATR-2026-01854-falsified-research-abstract-disinformation.yaml +82 -0
  119. package/rules/model-abuse/ATR-2026-01855-content-misappropriation-republish.yaml +90 -0
  120. package/rules/model-abuse/ATR-2026-01856-targeted-harmful-content-generation.yaml +142 -0
  121. package/rules/model-abuse/ATR-2026-01896-ransomware.yaml +124 -0
  122. package/rules/model-abuse/ATR-2026-01897-host-sabotage.yaml +169 -0
  123. package/rules/model-abuse/ATR-2026-01898-network-dos.yaml +133 -0
  124. package/rules/privilege-escalation/ATR-2026-01600-sql-injection-tautology-rbac-bypass.yaml +113 -0
  125. package/rules/privilege-escalation/ATR-2026-01601-sql-injection-destructive-ddl.yaml +118 -0
  126. package/rules/privilege-escalation/ATR-2026-01602-sql-injection-union-select-exfil.yaml +118 -0
  127. package/rules/privilege-escalation/ATR-2026-01603-sql-injection-stacked-dml-abuse.yaml +109 -0
  128. package/rules/privilege-escalation/ATR-2026-01604-sql-injection-schema-enumeration.yaml +105 -0
  129. package/rules/privilege-escalation/ATR-2026-01609-shell-injection-exfil-webhook.yaml +123 -0
  130. package/rules/privilege-escalation/ATR-2026-01610-shell-evasion-subshell-injection.yaml +114 -0
  131. package/rules/privilege-escalation/ATR-2026-01611-shell-evasion-eval-exec-injection.yaml +125 -0
  132. package/rules/privilege-escalation/ATR-2026-01612-debug-mode-privilege-escalation.yaml +119 -0
  133. package/rules/privilege-escalation/ATR-2026-01613-rbac-bypass-social-engineering.yaml +161 -0
  134. package/rules/privilege-escalation/ATR-2026-01614-bola-cross-user-data-access.yaml +141 -0
  135. package/rules/privilege-escalation/ATR-2026-01615-sandbox-escape-command-injection.yaml +119 -0
  136. package/rules/privilege-escalation/ATR-2026-01616-path-traversal-agent-file-access.yaml +106 -0
  137. package/rules/privilege-escalation/ATR-2026-01802-asb-backdoor-surveillance-implant.yaml +146 -0
  138. package/rules/privilege-escalation/ATR-2026-01803-asb-covert-server-intrusion.yaml +164 -0
  139. package/rules/privilege-escalation/ATR-2026-01808-asb-synthetic-pan-payment-probe.yaml +136 -0
  140. package/rules/privilege-escalation/ATR-2026-01899-remote-access-backdoor.yaml +152 -0
  141. package/rules/prompt-injection/ATR-2026-00490-garak-dan-in-order-to.yaml +4 -0
  142. package/rules/prompt-injection/ATR-2026-00492-garak-dan-want-you-to.yaml +2 -2
  143. package/rules/prompt-injection/ATR-2026-00495-garak-dan-insert-prompt-here.yaml +4 -0
  144. package/rules/prompt-injection/ATR-2026-00499-garak-dan-from-now-on.yaml +4 -0
  145. package/rules/prompt-injection/ATR-2026-00506-nevermind-override-goal-hijacking-in-user-input-promptinject.yaml +1 -1
  146. package/rules/prompt-injection/ATR-2026-00508-escape-delimiter-wrapped-goal-hijacking-in-user-input-prompt.yaml +4 -0
  147. package/rules/prompt-injection/ATR-2026-00579-mcp-tool-description-line-jumping-injection.yaml +214 -0
  148. package/rules/prompt-injection/ATR-2026-00584-indirect-injection-via-tool-response.yaml +234 -0
  149. package/rules/prompt-injection/ATR-2026-00700-structured-data-payload-injection.yaml +135 -0
  150. package/rules/prompt-injection/ATR-2026-00701-ipi-tool-output-xss-injection.yaml +121 -0
  151. package/rules/prompt-injection/ATR-2026-01000-context-ignore-fake-completion-prefix.yaml +123 -0
  152. package/rules/prompt-injection/ATR-2026-01001-direct-pi-instruction-override-secret-key.yaml +130 -0
  153. package/rules/prompt-injection/ATR-2026-01002-role-escalation-false-authority-claim.yaml +132 -0
  154. package/rules/prompt-injection/ATR-2026-01005-many-shot-repetition-override.yaml +117 -0
  155. package/rules/prompt-injection/ATR-2026-01006-payload-split-string-concat-injection.yaml +135 -0
  156. package/rules/prompt-injection/ATR-2026-01007-token-repeat-flooding-injection.yaml +117 -0
  157. package/rules/prompt-injection/ATR-2026-01009-virtual-world-bypass-fictional-pii.yaml +120 -0
  158. package/rules/prompt-injection/ATR-2026-01012-encoding-evasion-decode-execute.yaml +132 -0
  159. package/rules/prompt-injection/ATR-2026-01013-language-evasion-multilingual-credential.yaml +175 -0
  160. package/rules/prompt-injection/ATR-2026-01015-evasion-refusal-suppression.yaml +133 -0
  161. package/rules/prompt-injection/ATR-2026-01016-evasion-response-priming-forced-opener.yaml +121 -0
  162. package/rules/prompt-injection/ATR-2026-01017-evasion-dual-response-split-output.yaml +123 -0
  163. package/rules/prompt-injection/ATR-2026-01018-evasion-shell-injection-eval.yaml +212 -0
  164. package/rules/prompt-injection/ATR-2026-01019-sysprompt-override-fake-diagnostic-mode.yaml +146 -0
  165. package/rules/prompt-injection/ATR-2026-01020-spikee-doc-embedded-base64-payload.yaml +116 -0
  166. package/rules/prompt-injection/ATR-2026-01021-spikee-doc-embedded-translation-injection.yaml +114 -0
  167. package/rules/prompt-injection/ATR-2026-01023-evasion-opposite-intent-negation-trick.yaml +116 -0
  168. package/rules/prompt-injection/ATR-2026-01024-evasion-persona-override-rule-breaker.yaml +126 -0
  169. package/rules/prompt-injection/ATR-2026-01025-evasion-hypothetical-fictional-execution-framing.yaml +140 -0
  170. package/rules/prompt-injection/ATR-2026-01026-evasion-unicode-glitch-token-anomaly.yaml +131 -0
  171. package/rules/prompt-injection/ATR-2026-01304-indirect-injection-carrier-important-override.yaml +141 -0
  172. package/rules/prompt-injection/ATR-2026-01757-hypothetical-framing-bypass-research-audit.yaml +130 -0
  173. package/rules/prompt-injection/ATR-2026-01758-hypothetical-fictional-story-bypass.yaml +153 -0
  174. package/rules/prompt-injection/ATR-2026-01759-dos-new-important-instructions-injection-in-document.yaml +124 -0
  175. package/rules/prompt-injection/ATR-2026-01771-semantic-jailbreak-framing.yaml +291 -0
  176. package/rules/prompt-injection/ATR-2026-01800-asb-trigger-marker-tool-coercion.yaml +155 -0
  177. package/rules/prompt-injection/ATR-2026-01860-llmail-chat-template-boundary-spoof.yaml +142 -0
  178. package/rules/prompt-injection/ATR-2026-01861-llmail-pseudo-xml-role-injection.yaml +140 -0
  179. package/rules/prompt-injection/ATR-2026-01865-llmail-fake-email-boundary-marker.yaml +137 -0
  180. package/rules/prompt-injection/ATR-2026-01900-output-encoding.yaml +178 -0
  181. package/rules/prompt-injection/ATR-2026-01901-output-scrambling.yaml +169 -0
  182. package/rules/prompt-injection/ATR-2026-01902-output-emoji.yaml +112 -0
  183. package/rules/prompt-injection/ATR-2026-01903-output-language.yaml +105 -0
  184. package/rules/prompt-injection/ATR-2026-01904-link-injection.yaml +126 -0
  185. package/rules/prompt-injection/ATR-2026-01905-promotional-injection.yaml +108 -0
  186. package/rules/prompt-injection/ATR-2026-01906-content-manipulation.yaml +175 -0
  187. package/rules/prompt-injection/ATR-2026-01920-access-grant-coercion.yaml +160 -0
  188. package/rules/prompt-injection/ATR-2026-01921-access-denial-inversion.yaml +155 -0
  189. package/rules/prompt-injection/ATR-2026-01922-authorization-state-spoofing.yaml +160 -0
  190. package/rules/prompt-injection/ATR-2026-01923-forged-input-boundary-markers.yaml +160 -0
  191. package/rules/prompt-injection/ATR-2026-01925-encoded-payload-decoding-coercion.yaml +177 -0
  192. package/rules/prompt-injection/ATR-2026-01926-cross-lingual-authorization-laundering.yaml +149 -0
  193. package/rules/skill-compromise/ATR-2026-01755-backdoor-pot-linguistic-trigger-phrase.yaml +148 -0
  194. package/rules/skill-compromise/ATR-2026-01756-backdoor-pot-symbol-emoticon-trigger.yaml +147 -0
  195. package/rules/tool-poisoning/ATR-2026-00494-garak-exploitation-mixedunassigned.yaml +2 -2
  196. package/rules/tool-poisoning/ATR-2026-00577-create-mcp-server-stdio-exec-command-injection.yaml +186 -0
  197. package/rules/tool-poisoning/ATR-2026-00581-mcp-tool-rug-pull-post-approval-redefinition.yaml +210 -0
  198. package/rules/tool-poisoning/ATR-2026-00714-tool-camouflage-forced-tool-call.yaml +127 -0
  199. package/rules/tool-poisoning/ATR-2026-00715-tool-knowledge-hijack-identity-injection.yaml +143 -0
  200. package/rules/tool-poisoning/ATR-2026-00716-ipi-data-destruction-carrier.yaml +129 -0
  201. package/rules/tool-poisoning/ATR-2026-00720-tool-misuse-privilege-escalation-social.yaml +117 -0
  202. package/rules/tool-poisoning/ATR-2026-01300-mcp-notes-param-chat-history-exfil.yaml +150 -0
  203. package/rules/tool-poisoning/ATR-2026-01301-tool-description-exclusive-tool-override.yaml +140 -0
  204. package/rules/tool-poisoning/ATR-2026-01302-fake-tool-result-instruction-injection.yaml +134 -0
  205. package/rules/tool-poisoning/ATR-2026-01303-tool-schema-enumeration-social-engineering.yaml +170 -0
  206. package/rules/tool-poisoning/ATR-2026-01306-mcp-oauth-command-injection.yaml +134 -0
  207. package/rules/tool-poisoning/ATR-2026-01307-mcp-dns-rebinding-attack.yaml +140 -0
  208. package/rules/tool-poisoning/ATR-2026-01310-mcp-tool-description-compliance-history-exfil.yaml +162 -0
  209. package/rules/tool-poisoning/ATR-2026-01775-semantic-mcp-tool-manifest-poisoning.yaml +250 -0
  210. package/rules/tool-poisoning/ATR-2026-01927-mcp-server-kubernetes-kubectl-command-injection.yaml +171 -0
  211. package/rules/tool-poisoning/ATR-2026-01928-framelink-figma-mcp-curl-fallback-command-injection.yaml +230 -0
  212. package/spec/mappings/atr-to-nist-csf-2.0.md +1 -1
@@ -0,0 +1,201 @@
1
+ title: Zen MCP Server path-traversal blacklist bypass via non-canonical paths (CVE-2025-66689)
2
+ id: ATR-2026-00578
3
+ rule_version: 1
4
+ status: experimental
5
+ description: >
6
+ CVE-2025-66689 (CWE-22). The Zen MCP server's is_dangerous_path() blocks
7
+ sensitive files with an exact-string blacklist but never canonicalizes the
8
+ path before comparison, so a path that still resolves to a protected target
9
+ slips through when it is wrapped in normalization tricks: a blacklisted
10
+ prefix followed by ../ (/etc/shadow/../../../home/user/.ssh/id_rsa), a
11
+ same-directory bounce (/home/user/.ssh/../.ssh/id_rsa), a /./ no-op
12
+ (/etc/./shadow), or redundant slashes (/etc//shadow). The discriminator from
13
+ the existing deep-../-chain rule (ATR-2026-00569) and the clean-credential-path
14
+ rule (ATR-2026-00113) is that the SENSITIVE target token sits immediately
15
+ adjacent to a normalization/traversal artefact — neither a clean credential
16
+ path nor a bare ../ chain alone matches here.
17
+ author: "ATR Community (vulnerablemcp sync)"
18
+ date: 2026/06/12
19
+ schema_version: '0.1'
20
+ detection_tier: pattern
21
+ maturity: experimental
22
+ severity: high
23
+ references:
24
+ owasp_llm:
25
+ - "LLM07:2025 - System Prompt Leakage"
26
+ - "LLM02:2025 - Sensitive Information Disclosure"
27
+ owasp_agentic:
28
+ - "ASI05:2026 - Unexpected Code Execution"
29
+ - "ASI06:2026 - Memory and Context Poisoning"
30
+ mitre_atlas:
31
+ - "AML.T0057 - LLM Data Leakage"
32
+ - "AML.T0056 - LLM Meta Prompt Extraction"
33
+ cve:
34
+ - CVE-2025-66689
35
+ cwe:
36
+ - CWE-22
37
+ vulnerablemcp_id:
38
+ - cve-2025-66689-zen-mcp-path-traversal
39
+ external:
40
+ - https://www.sentinelone.com/vulnerability-database/cve-2025-66689/
41
+ metadata_provenance:
42
+ cve: vulnerablemcp-sync
43
+ cwe: vulnerablemcp-sync
44
+ vulnerablemcp: vulnerablemcp-sync
45
+ compliance:
46
+ owasp_agentic:
47
+ - id: ASI06:2026
48
+ context: "OWASP Agentic ASI06:2026 is exercised by path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689); this rule provides runtime detection of that technique."
49
+ strength: primary
50
+ - id: ASI05:2026
51
+ context: "OWASP Agentic ASI05:2026 is exercised by path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689); this rule provides runtime detection of that technique."
52
+ strength: secondary
53
+ owasp_llm:
54
+ - id: LLM02:2025
55
+ context: "OWASP LLM LLM02:2025 is exercised by path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689); this rule is a detection implementation for that category."
56
+ strength: primary
57
+ - id: LLM07:2025
58
+ context: "OWASP LLM LLM07:2025 is exercised by path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689); this rule is a detection implementation for that category."
59
+ strength: secondary
60
+ eu_ai_act:
61
+ - article: "15"
62
+ context: "EU AI Act Article 15 (accuracy, robustness and cybersecurity) requires controls against path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689); this rule provides runtime detection evidence for that obligation."
63
+ strength: primary
64
+ - article: "10"
65
+ context: "EU AI Act Article 10 (data and data governance) requires controls against path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689); this rule provides runtime detection evidence for that obligation."
66
+ strength: secondary
67
+ nist_ai_rmf:
68
+ - function: Measure
69
+ subcategory: MS.2.10
70
+ context: "NIST AI RMF MS.2.10 (privacy risk examined and documented) is supported by this rule's detection of path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689)."
71
+ strength: primary
72
+ - function: Measure
73
+ subcategory: MS.2.7
74
+ context: "NIST AI RMF MS.2.7 (security and resilience evaluated and documented) is supported by this rule's detection of path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689)."
75
+ strength: secondary
76
+ iso_42001:
77
+ - clause: "8.4"
78
+ context: "ISO/IEC 42001 Clause 8.4 (AI system impact assessment) is operationalised by this rule's detection of path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689)."
79
+ strength: primary
80
+ - clause: "9.1"
81
+ context: "ISO/IEC 42001 Clause 9.1 (monitoring, measurement, analysis and evaluation) is operationalised by this rule's detection of path-traversal blacklist bypass in Zen MCP Server that reads files outside the sandbox via non-canonical paths (CVE-2025-66689)."
82
+ strength: secondary
83
+
84
+ tags:
85
+ category: context-exfiltration
86
+ subcategory: path-normalization-bypass
87
+ scan_target: runtime
88
+ confidence: high
89
+ agent_source:
90
+ type: mcp_exchange
91
+ framework:
92
+ - any
93
+ provider:
94
+ - any
95
+ detection:
96
+ condition: any
97
+ false_positives:
98
+ - Documentation or tutorials that mention ../ relative imports without a sensitive credential/system target adjacent to it
99
+ - Legitimate absolute file paths to project source under /home/<user>/project that contain no /../ , /./ , or redundant-slash artefact
100
+ - Security write-ups quoting the CVE that describe canonicalization in prose rather than presenting an inline non-canonical path to a sensitive file
101
+ conditions:
102
+ - field: content
103
+ operator: regex
104
+ value: (?i)[\\/](?:etc[\\/](?:shadow|passwd|sudoers)|\.ssh|\.aws|\.config[\\/]gcloud|root)[\\/]\.{1,2}[\\/]{1,2}[^\s"'<>]{0,80}(?:id_(?:rsa|ed25519|ecdsa)|\.ssh|shadow|passwd|credentials|authorized_keys|\.pem|\.key)
105
+ description: Blacklisted sensitive prefix immediately followed by a ./ or ../ normalization hop that re-targets another sensitive file (Zen-MCP prefix-then-traversal bypass)
106
+ - field: content
107
+ operator: regex
108
+ value: (?i)[\\/]etc[\\/]\.{1,2}[\\/]{1,2}(?:etc[\\/]){0,1}(?:shadow|passwd|sudoers)\b
109
+ description: /etc/./shadow or /etc/../etc/shadow style same-dir or bounce normalization reaching an exact-blacklist target
110
+ - field: content
111
+ operator: regex
112
+ value: (?i)[\\/]\.ssh[\\/]\.\.[\\/]\.ssh[\\/](?:id_(?:rsa|ed25519|ecdsa)|authorized_keys|known_hosts)\b
113
+ description: .ssh/../.ssh/ same-directory bounce that re-resolves to an SSH private key while evading an exact ~/.ssh/id_rsa blacklist entry
114
+ - field: content
115
+ operator: regex
116
+ value: (?i)/etc/{2,}(?:shadow|passwd|sudoers)\b|/\.ssh/{2,}id_(?:rsa|ed25519|ecdsa)\b
117
+ description: Redundant FORWARD-slash variant (/etc//shadow , /.ssh//id_rsa) that defeats an exact-string blacklist while resolving to the protected file. Forward-slash only — backslash forms like \etc\\passwd are almost always doc/Windows-escaping in tutorials, not a unix redundant-slash bypass, and caused a wild FP.
118
+ response:
119
+ actions:
120
+ - alert
121
+ - block_tool
122
+ message_template: >
123
+ [ATR-2026-00578] Non-canonical path to a sensitive file detected
124
+ (CVE-2025-66689, Zen MCP is_dangerous_path blacklist bypass). The path mixes
125
+ a sensitive target (SSH key, /etc/shadow, credentials) with a normalization
126
+ or traversal artefact (../ , /./ , redundant slash, blacklisted-prefix-then-..)
127
+ that evades exact-string blacklists while still resolving to the protected
128
+ file. Remediation: upgrade Zen MCP server to v9.8.2 or later; canonicalize
129
+ paths (resolve symlinks, normalize . and ..) BEFORE any security check; prefer
130
+ an allowlist of permitted directories over a sensitive-path blacklist.
131
+ notify:
132
+ - security_team
133
+ confidence: 85
134
+ wild_fp_rate: 0
135
+ test_cases:
136
+ true_positives:
137
+ - input: '{"path": "/etc/shadow/../../../home/user/.ssh/id_rsa"}'
138
+ expected: triggered
139
+ description: Blacklisted /etc/shadow prefix then ../ chain re-targeting an SSH private key (CVE-2025-66689 PoC)
140
+ - input: read_file("/home/user/.ssh/../.ssh/id_rsa")
141
+ expected: triggered
142
+ description: .ssh/../.ssh/ same-directory bounce evading exact ~/.ssh/id_rsa blacklist
143
+ - input: 'requested file: /etc/./shadow'
144
+ expected: triggered
145
+ description: /etc/./shadow no-op normalization reaching exact blacklist target
146
+ - input: open("/etc//shadow")
147
+ expected: triggered
148
+ description: Redundant-slash variant defeating exact-string match on /etc/shadow
149
+ - input: '{"file": "/root/.ssh/../.ssh/id_ed25519"}'
150
+ expected: triggered
151
+ description: root .ssh bounce to ed25519 private key
152
+ - input: path=/etc/../etc/passwd
153
+ expected: triggered
154
+ description: /etc/../etc/passwd bounce normalization to /etc/passwd
155
+ - input: load("/home/user/.aws/../.ssh/id_rsa")
156
+ expected: triggered
157
+ description: Blacklisted .aws prefix then ../ hop re-targeting an SSH key
158
+ true_negatives:
159
+ - input: path = "/home/user/project/main.py"
160
+ expected: not_triggered
161
+ description: Legit absolute project source path, no normalization artefact or sensitive target
162
+ - input: import "../../shared/utils"
163
+ expected: not_triggered
164
+ description: Normal relative import path, no sensitive credential/system target
165
+ - input: To go up a directory in the tutorial, use ../ before the folder name.
166
+ expected: not_triggered
167
+ description: Documentation sentence mentioning ../ with no sensitive target adjacent
168
+ - input: CVE-2025-66689 is fixed by canonicalizing paths before the blacklist check in is_dangerous_path().
169
+ expected: not_triggered
170
+ description: CVE patch-discussion prose, describes the fix without an inline non-canonical sensitive path
171
+ - input: We studied path-traversal bypasses where attackers reach SSH keys via redundant slashes and dot segments.
172
+ expected: not_triggered
173
+ description: Research abstract describing the technique in prose, no literal payload
174
+ - input: ssh-keygen -lf ~/.ssh/id_rsa
175
+ expected: not_triggered
176
+ description: Clean ~/.ssh/id_rsa path with no traversal/normalization artefact (owned by ATR-2026-00113)
177
+ - input: relpath = "../../../build/output/lib.so"
178
+ expected: not_triggered
179
+ description: Deep ../ chain to a build artefact, not a sensitive target (no overlap with ATR-2026-00569 either)
180
+ - input: cp /etc/passwd.bak /home/user/backup/passwd.copy
181
+ expected: not_triggered
182
+ description: Backup copy of passwd-like files via clean absolute paths, no normalization artefact
183
+ - input: 'In this lab, requesting \etc\\passwd demonstrates the path-traversal example.'
184
+ expected: not_triggered
185
+ description: Security-education skill quoting a backslash-escaped \etc\passwd example (wild FP from skills-sh/sickn33 file-path-traversal.md) — backslash form is doc-escaping, not a unix redundant-slash bypass
186
+ _llm_authored:
187
+ model: claude (gstack subagent)
188
+ generalization_note: >
189
+ Generalizes the Zen-MCP is_dangerous_path() exact-blacklist bypass beyond the
190
+ two literal PoCs (/home/user/.ssh/../.ssh/id_rsa and /etc/./shadow) by keying
191
+ on the structural invariant of the bug class: a SENSITIVE target token
192
+ (id_rsa/ed25519/ecdsa, /etc/shadow|passwd|sudoers, credentials, authorized_keys,
193
+ .pem/.key) appearing ADJACENT to a path-normalization artefact (blacklisted
194
+ prefix then ../ , same-dir .ssh/../.ssh/ bounce, /./ no-op, /etc/../etc bounce,
195
+ or redundant slashes). This is deliberately disjoint from ATR-2026-00569
196
+ (requires 2+ consecutive ../ hops to a system target — a clean deep chain, no
197
+ prefix/bounce/normalization adjacency) and from ATR-2026-00113 (clean
198
+ credential paths with no traversal), so a bare ../ chain or a clean
199
+ ~/.ssh/id_rsa does not trigger this rule. Bounded {0,80}/{1,2} spans keep the
200
+ regex linear and avoid catastrophic backtracking.
201
+ note: Generation-time authoring; verified by deterministic gate. Runtime detection is pure regex. Human review required before merge.
@@ -0,0 +1,220 @@
1
+ title: MCP session ID / auth token placed in URL query string (session leak via logs, referrer, history)
2
+ id: ATR-2026-00580
3
+ rule_version: 1
4
+ status: experimental
5
+ description: >
6
+ Vulnerable MCP Project entry "session-ids-exposed-in-urls" (reported by
7
+ Equixly). An MCP server, gateway, or client construction embeds a session
8
+ identifier or auth credential in the URL QUERY STRING rather than in a
9
+ request header or POST body — e.g. GET /messages/?sessionId=<uuid>,
10
+ https://mcp.example.com/sse?session_id=<value>, or a config "url" field with
11
+ ?access_token=/?api_key=. URLs are routinely logged by web servers, proxies,
12
+ CDNs, and browser history, and are leaked in HTTP Referer headers on outbound
13
+ navigation, so a credential in the query string is an exposed credential —
14
+ enabling session hijack and context exfiltration. The discriminator from the
15
+ generic secret-assignment rule (ATR-2026-00021, which matches any
16
+ api_key=/access_token= at-rest assignment) and from the markdown-image-exfil
17
+ rules (00261/00405/00501, which key on ![](url?param=) image/link syntax) is
18
+ that THIS rule requires a session/auth credential keyword to sit in the QUERY
19
+ STRING of an http(s)/ws(s) URL or an MCP-shaped relative endpoint
20
+ (/messages, /sse, /mcp, or a config url= field) with a realistic (12+ char)
21
+ credential value — not a credential assigned to an env var, not a path
22
+ segment like /api-keys, and not a doc placeholder like ?session_token=5e9...
23
+ author: "ATR Community (vulnerablemcp sync)"
24
+ date: 2026/06/12
25
+ schema_version: '0.1'
26
+ detection_tier: pattern
27
+ maturity: experimental
28
+ severity: high
29
+ references:
30
+ owasp_llm:
31
+ - "LLM07:2025 - System Prompt Leakage"
32
+ - "LLM02:2025 - Sensitive Information Disclosure"
33
+ owasp_agentic:
34
+ - "ASI05:2026 - Unexpected Code Execution"
35
+ - "ASI06:2026 - Memory and Context Poisoning"
36
+ mitre_atlas:
37
+ - "AML.T0057 - LLM Data Leakage"
38
+ - "AML.T0056 - LLM Meta Prompt Extraction"
39
+ vulnerablemcp_id:
40
+ - session-ids-exposed-in-urls
41
+ external:
42
+ - https://equixly.com/blog/2025/03/29/mcp-server-new-security-nightmare/
43
+ metadata_provenance:
44
+ vulnerablemcp: vulnerablemcp-sync
45
+ compliance:
46
+ owasp_agentic:
47
+ - id: ASI06:2026
48
+ context: "OWASP Agentic ASI06:2026 is exercised by leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history); this rule provides runtime detection of that technique."
49
+ strength: primary
50
+ - id: ASI05:2026
51
+ context: "OWASP Agentic ASI05:2026 is exercised by leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history); this rule provides runtime detection of that technique."
52
+ strength: secondary
53
+ owasp_llm:
54
+ - id: LLM02:2025
55
+ context: "OWASP LLM LLM02:2025 is exercised by leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history); this rule is a detection implementation for that category."
56
+ strength: primary
57
+ - id: LLM07:2025
58
+ context: "OWASP LLM LLM07:2025 is exercised by leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history); this rule is a detection implementation for that category."
59
+ strength: secondary
60
+ eu_ai_act:
61
+ - article: "15"
62
+ context: "EU AI Act Article 15 (accuracy, robustness and cybersecurity) requires controls against leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history); this rule provides runtime detection evidence for that obligation."
63
+ strength: primary
64
+ - article: "10"
65
+ context: "EU AI Act Article 10 (data and data governance) requires controls against leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history); this rule provides runtime detection evidence for that obligation."
66
+ strength: secondary
67
+ nist_ai_rmf:
68
+ - function: Measure
69
+ subcategory: MS.2.10
70
+ context: "NIST AI RMF MS.2.10 (privacy risk examined and documented) is supported by this rule's detection of leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history)."
71
+ strength: primary
72
+ - function: Measure
73
+ subcategory: MS.2.7
74
+ context: "NIST AI RMF MS.2.7 (security and resilience evaluated and documented) is supported by this rule's detection of leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history)."
75
+ strength: secondary
76
+ iso_42001:
77
+ - clause: "8.4"
78
+ context: "ISO/IEC 42001 Clause 8.4 (AI system impact assessment) is operationalised by this rule's detection of leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history)."
79
+ strength: primary
80
+ - clause: "9.1"
81
+ context: "ISO/IEC 42001 Clause 9.1 (monitoring, measurement, analysis and evaluation) is operationalised by this rule's detection of leakage of MCP session IDs and auth tokens placed in URL query strings (exposed via logs, referrer headers, and history)."
82
+ strength: secondary
83
+
84
+ tags:
85
+ category: context-exfiltration
86
+ subcategory: session-credential-in-url-query
87
+ scan_target: runtime
88
+ confidence: high
89
+ agent_source:
90
+ type: mcp_exchange
91
+ framework:
92
+ - any
93
+ provider:
94
+ - any
95
+ detection:
96
+ condition: any
97
+ false_positives:
98
+ - URLs with non-credential query parameters only (?page=2, ?q=search, ?city=NYC) — no session/auth credential keyword in the query string
99
+ - Credential keyword as a documentation path segment (/api-keys, /access-tokens/, /settings/auth-tokens/) with no =value query parameter
100
+ - 'Environment-variable or config assignment of a credential that is NOT inside a URL query (export API_KEY=..., SESSION_ID=... env, "Authorization: Bearer ..." header examples)'
101
+ - Documentation placeholders with a redacted/short value (?session_token=5e9..., ?apiKey=KEY) — the 12+ char realistic-value bound excludes these
102
+ - Uppercase or single-word placeholder token values (?access_token=ACCESS_TOKEN, ?apiKey=YOUR_API_KEY, ?sessionId=attacker_session, ?token=your_token_here) — the require-a-digit value shape excludes these, so API docs and security-teaching examples that show the pattern with a placeholder value do not match
103
+ - Prose that mentions "session id in a URL" as a best-practice warning without an inline credential-bearing URL
104
+ conditions:
105
+ - field: content
106
+ operator: regex
107
+ value: (?i)(?:https?|wss?):\/\/[A-Za-z0-9.@:\/_~%+-]{1,120}\?[A-Za-z0-9._~%+\/=&-]{0,80}?\b(?:session[_-]?id|sessionid|session[_-]?token|auth[_-]?token|access[_-]?token|api[_-]?key)=(?=[A-Za-z0-9._~+\/-]*[0-9])[A-Za-z0-9._~+\/-]{12,}
108
+ description: A session/auth credential keyword carrying a realistic high-entropy (12+ char, contains a digit) value inside the query string of an http(s)/ws(s) URL (session leak via logs/referrer/history). The digit requirement excludes uppercase/word placeholders (ACCESS_TOKEN, YOUR_API_KEY, attacker_session) that survive the engine's case-insensitive matching.
109
+ - field: content
110
+ operator: regex
111
+ value: (?i)\b(?:GET|POST|url["']?\s*[:=]\s*["']?)\s*\/[A-Za-z0-9._~%+\/-]{0,60}\?[A-Za-z0-9._~%+\/=&-]{0,60}?\b(?:session[_-]?id|sessionid|session[_-]?token|auth[_-]?token|access[_-]?token|api[_-]?key)=(?=[A-Za-z0-9._~+\/-]*[0-9])[A-Za-z0-9._~+\/-]{12,}
112
+ description: An MCP/SSE-shaped relative endpoint (request line or config url field, e.g. GET /messages/?sessionId=..., url=/sse?session_id=...) carrying a realistic high-entropy credential (12+ char, contains a digit) in the query string
113
+ response:
114
+ actions:
115
+ - alert
116
+ - block_tool
117
+ message_template: >
118
+ [ATR-2026-00580] A session ID or auth credential is being placed in a URL
119
+ query string (Vulnerable MCP "session-ids-exposed-in-urls", reported by
120
+ Equixly). URLs are logged by servers, proxies, CDNs and browser history and
121
+ leak via HTTP Referer headers, so a credential in the query string is an
122
+ exposed credential — enabling MCP session hijack and context exfiltration.
123
+ Remediation: never put session IDs or tokens in the URL. Send them in an
124
+ HTTP header (Authorization: Bearer ...) or a POST request body; use
125
+ short-lived, rotating session tokens; serve everything over HTTPS; and
126
+ scrub session identifiers from proxy/server access logs.
127
+ notify:
128
+ - security_team
129
+ confidence: 82
130
+ wild_fp_rate: 0
131
+ test_cases:
132
+ true_positives:
133
+ - input: https://mcp.example.com/sse?session_id=abc123def456ghi789
134
+ expected: triggered
135
+ description: MCP SSE endpoint URL with a session_id credential in the query string
136
+ - input: 'GET /messages/?sessionId=550e8400-e29b-41d4-a716-446655440000'
137
+ expected: triggered
138
+ description: Canonical MCP SSE transport request line placing the session UUID in the URL query (Equixly PoC form)
139
+ - input: 'endpoint: https://mcp.acme.io/connect?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'
140
+ expected: triggered
141
+ description: MCP connect URL carrying a JWT access_token in the query string
142
+ - input: '{"url": "https://gateway.tool.dev/mcp?api_key=sk-live-9f8e7d6c5b4a3210"}'
143
+ expected: triggered
144
+ description: MCP client config with the server api_key embedded in the URL query
145
+ - input: wss://realtime.example.org/stream?auth_token=A1b2C3d4E5f6G7h8I9j0
146
+ expected: triggered
147
+ description: WebSocket MCP transport with an auth_token in the query string (logged by proxies/CDNs)
148
+ - input: 'url=/sse?session_id=abc123def456ghi789jkl'
149
+ expected: triggered
150
+ description: Relative config url field placing a session_id in the SSE endpoint query string
151
+ - input: 'POST /mcp/stream?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'
152
+ expected: triggered
153
+ description: MCP stream request line with an access_token in the query string
154
+ true_negatives:
155
+ - input: https://api.example.com/search?q=hello&page=2
156
+ expected: not_triggered
157
+ description: Ordinary URL with only non-credential query params (q, page)
158
+ - input: Use the Authorization Bearer header instead of putting the token in the URL.
159
+ expected: not_triggered
160
+ description: Remediation prose recommending header-based auth — no credential-bearing URL
161
+ - input: SESSION_ID=local1234567890 set as an environment variable for the test runner
162
+ expected: not_triggered
163
+ description: Credential assigned to an env var, not inside a URL query string
164
+ - input: wss://connect.browser-use.com?apiKey=KEY&proxyCountryCode=us
165
+ expected: not_triggered
166
+ description: Documented WebSocket URL whose apiKey value is the literal placeholder KEY (under the 12-char realistic-value bound)
167
+ - input: https://connect.maton.ai/?session_token=5e9...
168
+ expected: not_triggered
169
+ description: Benign API doc with a redacted/truncated session_token placeholder (5e9... is under the 12-char realistic-value bound)
170
+ - input: The session id should never be exposed in a URL query string per best practice.
171
+ expected: not_triggered
172
+ description: Best-practice warning prose mentioning the concept with no inline credential-bearing URL
173
+ - input: https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=123&redirect_uri=https://app.example.com/callback
174
+ expected: not_triggered
175
+ description: Standard OAuth authorization-code redirect (response_type=code, no session/auth-token credential keyword in the query)
176
+ - input: 'GET /v1/users?page=2&limit=50'
177
+ expected: not_triggered
178
+ description: Normal REST request line with pagination params, no credential in the query
179
+ - input: 'documentation link: https://sentry.io/settings/auth-tokens/'
180
+ expected: not_triggered
181
+ description: Credential keyword appears only as a path segment (/auth-tokens/), not a =value query parameter
182
+ - input: https://api.weixin.qq.com/cgi-bin/draft/add?access_token=ACCESS_TOKEN
183
+ expected: not_triggered
184
+ description: WeChat API documentation URL whose access_token value is the uppercase placeholder ACCESS_TOKEN — no digit, so the require-a-digit value shape excludes it (wild FP from real-skill scan)
185
+ - input: https://target.com/login?SESSIONID=attacker_session
186
+ expected: not_triggered
187
+ description: Security-education example (broken-authentication.md) showing the session-fixation vuln with a teaching placeholder value attacker_session — no digit, excluded by value shape (wild FP from real-skill scan)
188
+ _llm_authored:
189
+ model: claude (gstack subagent)
190
+ generalization_note: >
191
+ Generalizes the Vulnerable MCP "session-ids-exposed-in-urls" advisory beyond
192
+ its single canonical example (GET /messages/?sessionId=UUID) by keying on the
193
+ structural invariant of the bug class: a session/auth credential keyword
194
+ (session_id, sessionid, session_token, auth_token, access_token, api_key)
195
+ appearing as a QUERY-STRING parameter (preceded by ? or & inside the query)
196
+ of either an absolute http(s)/ws(s) URL (condition 1) or an MCP/SSE-shaped
197
+ relative endpoint or config url field (condition 2), carrying a realistic
198
+ 12+ character credential value that CONTAINS A DIGIT. Two precision
199
+ discriminators stack: (1) the 12+ char length bound excludes short
200
+ placeholders (?session_token=5e9..., ?apiKey=KEY); (2) the require-a-digit
201
+ value shape — a (?=[A-Za-z0-9._~+/-]*[0-9]) lookahead before the value —
202
+ excludes letters-only / uppercase placeholders. The digit requirement is
203
+ deliberately chosen instead of a case-sensitive lowercase check because the
204
+ ATR engine strips inline (?i) and applies the case-insensitive flag
205
+ globally, so a [a-z] check would still match uppercase; a digit is the
206
+ case-fold-stable signal. This drops the wild false positives found scanning
207
+ 3115 real skills — a WeChat API doc (?access_token=ACCESS_TOKEN) and a
208
+ security-teaching example (?SESSIONID=attacker_session) — plus the
209
+ YOUR_API_KEY / your_token_here / REDACTED placeholder family, while still
210
+ catching real UUIDs (550e8400-...), JWTs (eyJ...digits...) and live keys
211
+ (sk-live-9f8e7d6c...), which all contain digits. Deliberately disjoint from
212
+ ATR-2026-00021 (generic at-rest credential ASSIGNMENT, no URL-query
213
+ requirement), from the markdown-image-exfil rules 00261/00405/00501 (which
214
+ require ![](...) image/link markdown syntax), and from ATR-2026-00114
215
+ (OAuth redirect_uri / forwarding-verb patterns). Path-segment credential
216
+ keywords (/api-keys, /access-tokens/) and env-var assignments do not match
217
+ because the credential must be a =value query parameter inside a URL.
218
+ Bounded {0,80}/{0,60}/{1,120} spans keep the regex linear (no unbounded
219
+ [^...]* or .*) and avoid catastrophic backtracking.
220
+ note: Generation-time authoring; verified by deterministic gate. Runtime detection is pure regex. Human review required before merge.
@@ -0,0 +1,218 @@
1
+ title: MCP/agent tool reads .env or secret file without user consent (OSV-MCPS-2025-EB70F912)
2
+ id: ATR-2026-00583
3
+ rule_version: 1
4
+ status: experimental
5
+ description: >
6
+ CSA MCP-Security advisory OSV-MCPS-2025-EB70F912 (CWE-200 / CWE-922). An
7
+ MCP/agent file-read tool (Claude Code class) ingests a `.env` / secret file
8
+ by default during codebase analysis, sending API keys, DB credentials and
9
+ other secrets to the model/server with no explicit user-consent step. The
10
+ detectable artefact is the TOOL-CALL itself: a read/fs tool invocation whose
11
+ PATH ARGUMENT targets `.env`, `.env.local`, `secrets.*`, `credentials`,
12
+ `.npmrc` or `.netrc` — in function-call form `read_file(".env")` /
13
+ `Read(file_path="/app/.env.local")` or JSON-arg form `{"path":".env"}` /
14
+ `{"file_path":"~/project/.env"}`.
15
+
16
+ Discriminator from existing credential rules: this keys on the structured
17
+ MCP tool-mediated file-read shape (a read-tool name + quoted secret-file path
18
+ argument), which the other rules do NOT cover. ATR-2026-00115 (env-var
19
+ harvesting) only matches a shell verb `cat|read|load|parse` immediately
20
+ followed by a bare ` .env` token, not `read_file(".env")` or `{"path":".env"}`.
21
+ ATR-2026-00113 (credential theft) keys on home-dir credential PATHS and
22
+ `cat|read` of credential keywords, not the tool-call/JSON-arg `.env` form.
23
+ ATR-2026-00423 (NL sensitive-file disclosure) keys on natural-language
24
+ imperatives ("always include the contents of ..."), not a tool_input object.
25
+ ATR-2026-00569 / 00578 require a path-traversal / normalization artefact;
26
+ this rule fires on a CLEAN consent-less `.env` read with no traversal.
27
+ author: "ATR Community (mcp-security-db sync)"
28
+ date: 2026/06/12
29
+ schema_version: '0.1'
30
+ detection_tier: pattern
31
+ maturity: experimental
32
+ severity: high
33
+ references:
34
+ owasp_llm:
35
+ - "LLM07:2025 - System Prompt Leakage"
36
+ - "LLM02:2025 - Sensitive Information Disclosure"
37
+ owasp_agentic:
38
+ - "ASI05:2026 - Unexpected Code Execution"
39
+ - "ASI06:2026 - Memory and Context Poisoning"
40
+ mitre_atlas:
41
+ - "AML.T0057 - LLM Data Leakage"
42
+ - "AML.T0056 - LLM Meta Prompt Extraction"
43
+ cwe:
44
+ - CWE-200
45
+ - CWE-922
46
+ mcps_id:
47
+ - OSV-MCPS-2025-EB70F912
48
+ external:
49
+ - https://github.com/ModelContextProtocol-Security/vulnerability-db/blob/main/advisories/2025/07/16/OSV-MCPS-2025-EB70F912-osv.json
50
+ - https://github.com/anthropics/claude-code/issues/112
51
+ - https://github.com/anthropics/claude-code/issues/401
52
+ - https://github.com/anthropics/claude-code/issues/2695
53
+ - https://docs.anthropic.com/en/docs/claude-code/security
54
+ metadata_provenance:
55
+ cwe: mcp-security-db-sync
56
+ mcps_id: mcp-security-db-sync
57
+ compliance:
58
+ owasp_agentic:
59
+ - id: ASI06:2026
60
+ context: "OWASP Agentic ASI06:2026 is exercised by an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912); this rule provides runtime detection of that technique."
61
+ strength: primary
62
+ - id: ASI05:2026
63
+ context: "OWASP Agentic ASI05:2026 is exercised by an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912); this rule provides runtime detection of that technique."
64
+ strength: secondary
65
+ owasp_llm:
66
+ - id: LLM02:2025
67
+ context: "OWASP LLM LLM02:2025 is exercised by an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912); this rule is a detection implementation for that category."
68
+ strength: primary
69
+ - id: LLM07:2025
70
+ context: "OWASP LLM LLM07:2025 is exercised by an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912); this rule is a detection implementation for that category."
71
+ strength: secondary
72
+ eu_ai_act:
73
+ - article: "15"
74
+ context: "EU AI Act Article 15 (accuracy, robustness and cybersecurity) requires controls against an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912); this rule provides runtime detection evidence for that obligation."
75
+ strength: primary
76
+ - article: "10"
77
+ context: "EU AI Act Article 10 (data and data governance) requires controls against an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912); this rule provides runtime detection evidence for that obligation."
78
+ strength: secondary
79
+ nist_ai_rmf:
80
+ - function: Measure
81
+ subcategory: MS.2.10
82
+ context: "NIST AI RMF MS.2.10 (privacy risk examined and documented) is supported by this rule's detection of an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912)."
83
+ strength: primary
84
+ - function: Measure
85
+ subcategory: MS.2.7
86
+ context: "NIST AI RMF MS.2.7 (security and resilience evaluated and documented) is supported by this rule's detection of an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912)."
87
+ strength: secondary
88
+ iso_42001:
89
+ - clause: "8.4"
90
+ context: "ISO/IEC 42001 Clause 8.4 (AI system impact assessment) is operationalised by this rule's detection of an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912)."
91
+ strength: primary
92
+ - clause: "9.1"
93
+ context: "ISO/IEC 42001 Clause 9.1 (monitoring, measurement, analysis and evaluation) is operationalised by this rule's detection of an MCP/agent tool reading .env or secret files without user consent (OSV-MCPS-2025-EB70F912)."
94
+ strength: secondary
95
+
96
+ tags:
97
+ category: context-exfiltration
98
+ subcategory: mcp-consentless-secret-read
99
+ scan_target: mcp
100
+ confidence: high
101
+ agent_source:
102
+ type: mcp_exchange
103
+ framework:
104
+ - any
105
+ provider:
106
+ - any
107
+ detection:
108
+ condition: any
109
+ false_positives:
110
+ - Natural-language prose that merely mentions a .env / secrets file ("create a .env file with your API key", "if you have a .env file in your project root") with no read-tool call or JSON path argument.
111
+ - "The CLI flag form `node --env-file=.env` or `--env-file <path-to-.env>` — an interpreter loading its own config, not an agent read-tool ingesting the file content for the model."
112
+ - "`dotenv.config()` / `load_dotenv()` in normal application source — runtime config loading by the app itself, not an MCP read tool surfacing secrets to the agent."
113
+ - Searching/listing for the file (`find . -name ".env" -type f`) without reading its contents.
114
+ - A read tool whose path argument targets a NON-secret config file (config.json, README.md, src/index.ts).
115
+ conditions:
116
+ - field: content
117
+ operator: regex
118
+ value: (?i)\b(?:read_?file|readfile|read_text|read_secret|get_?file|load_?file|cat_?file|fs[._]read(?:file)?|open_?file|file_read|read)\s*\(\s*(?:file_?path|path|file)?\s*=?\s*["\x27](?:[^"\x27<>]{0,120}[\\/])?(?:\.?env(?:\.[\w.]+)?|secrets?(?:\.\w+)?|credentials|\.npmrc|\.netrc)["\x27]
119
+ description: A read/fs tool invoked in function-call form whose quoted path argument targets a .env or secret file (e.g. read_file(".env"), Read(file_path="/app/.env.local"), open_file("secrets/.env")) — MCP-mediated consent-less secret read.
120
+ - field: content
121
+ operator: regex
122
+ value: (?i)"(?:file_?path|path|file|filename|target|src|source)"\s*:\s*"(?:[^"<>]{0,120}[\\/])?(?:\.?env(?:\.[\w.]+)?|secrets?(?:\.\w+)?|credentials|\.npmrc|\.netrc)"
123
+ description: A JSON tool_input object whose path/file key value targets a .env or secret file (e.g. {"path":".env"}, {"file_path":"~/project/.env"}) — structured MCP tool-call ingesting secrets without a consent gate.
124
+ response:
125
+ actions:
126
+ - alert
127
+ message_template: >
128
+ [ATR-2026-00583] An MCP/agent read tool is targeting a .env / secret file
129
+ (.env, .env.local, secrets.*, credentials, .npmrc, .netrc) via its path
130
+ argument with no consent gate (OSV-MCPS-2025-EB70F912, CWE-200/CWE-922).
131
+ This exfiltrates API keys, DB credentials and other secrets into the model
132
+ context by default. Remediation: require an explicit user-consent prompt
133
+ before any tool reads secret files; add a read-deny rule for .env / secret
134
+ patterns in the agent settings (e.g. ~/.claude/settings.json deny list);
135
+ keep .env in .gitignore / .claudeignore; prefer a real secrets manager over
136
+ plaintext .env files and rotate any credentials already exposed.
137
+ notify:
138
+ - security_team
139
+ confidence: 80
140
+ wild_fp_rate: 0
141
+ test_cases:
142
+ true_positives:
143
+ - input: '{"tool":"read_file","arguments":{"path":".env"}}'
144
+ expected: triggered
145
+ description: MCP read_file tool with JSON path argument targeting a bare .env file
146
+ - input: Read(file_path="/app/.env.local")
147
+ expected: triggered
148
+ description: Claude Code Read tool function-call ingesting .env.local without consent
149
+ - input: '{"name":"fs.read","path":"config/.env"}'
150
+ expected: triggered
151
+ description: fs.read MCP tool with JSON path key targeting a project .env file
152
+ - input: read_file("/proj/.env")
153
+ expected: triggered
154
+ description: Function-call read of an absolute-path .env file
155
+ - input: readFile(".env.production")
156
+ expected: triggered
157
+ description: camelCase readFile tool targeting a .env.production secret file
158
+ - input: '{"tool":"fs.readFile","file_path":"~/project/.env"}'
159
+ expected: triggered
160
+ description: JSON file_path key with home-relative .env path in an fs.readFile tool call
161
+ - input: open_file("secrets/.env")
162
+ expected: triggered
163
+ description: open_file tool reading a .env under a secrets directory
164
+ - input: load_file("/srv/app/credentials")
165
+ expected: triggered
166
+ description: load_file tool reading a credentials secret file argument
167
+ true_negatives:
168
+ - input: 'If you have a `.env` file in your project root, the skill will load it for configuration.'
169
+ expected: not_triggered
170
+ description: NL prose mentioning .env, no read-tool call or JSON path argument (owned-by-prose, not a tool invocation)
171
+ - input: Create a .env file with your API key APIFY_TOKEN=your_token
172
+ expected: not_triggered
173
+ description: Tutorial instruction to create a .env file, not a read-tool reading its contents
174
+ - input: node --env-file=.env scripts/run.js
175
+ expected: not_triggered
176
+ description: Node CLI --env-file flag loading its own config, not an agent read tool surfacing secrets
177
+ - input: Use `--env-file <path-to-.env>` with all commands
178
+ expected: not_triggered
179
+ description: Documentation of the --env-file CLI flag, not a tool-call path argument
180
+ - input: find . -name ".env" -type f 2>/dev/null | head -5
181
+ expected: not_triggered
182
+ description: Searching/listing for .env files, no content read
183
+ - input: dotenv.config()
184
+ expected: not_triggered
185
+ description: App-side dotenv runtime config loading, not an MCP read tool
186
+ - input: 'The application loads .env files at startup using the dotenv package for configuration.'
187
+ expected: not_triggered
188
+ description: Prose describing dotenv usage, no tool invocation
189
+ - input: read_file("config.json")
190
+ expected: not_triggered
191
+ description: Read tool targeting a non-secret config.json file
192
+ - input: '{"path":"src/index.ts"}'
193
+ expected: not_triggered
194
+ description: JSON path argument targeting ordinary source, not a secret file
195
+ - input: Read(file_path="README.md")
196
+ expected: not_triggered
197
+ description: Read tool targeting documentation, no secret-file path
198
+ - input: 'If the user reports a credential leak, ask them whether ~/.aws/credentials was committed to git history.'
199
+ expected: not_triggered
200
+ description: Security advice prose referencing credentials, no read-tool path argument (owned by ATR-2026-00113)
201
+ _llm_authored:
202
+ model: claude-opus (gstack subagent)
203
+ generalization_note: >
204
+ Carves a signature DISJOINT from the existing credential cluster by keying on
205
+ the structured MCP/agent tool-call shape only: a read/fs tool NAME
206
+ (read_file/readFile/fs.read/Read/open_file/load_file/...) immediately
207
+ followed by a quoted PATH ARGUMENT (function-call or JSON path/file/file_path
208
+ key) whose basename is a secret file (.env[.suffix], secrets.*, credentials,
209
+ .npmrc, .netrc). ATR-2026-00115 requires a shell verb (cat|read|load|parse)
210
+ directly preceding a bare ` .env` token and does NOT match read_file(".env")
211
+ or {"path":".env"} (verified). ATR-2026-00113 keys on home-dir credential
212
+ PATHS and cat/read of credential keywords; ATR-2026-00423 keys on NL
213
+ imperatives; ATR-2026-00569/00578 require a traversal/normalization artefact.
214
+ Bounded {0,120} path span keeps both regexes linear (no nested quantifier on
215
+ backtrackable groups) avoiding catastrophic backtracking. The CLI flag form
216
+ --env-file=.env, find-by-name, dotenv.config(), and prose mentions are all
217
+ excluded because none present a read-TOOL-name + quoted secret path argument.
218
+ note: Generation-time authoring; runtime detection is pure regex. Verified by the deterministic safety gate (0 FP across benign corpora + no cross-rule conflict). Human review required before any production promotion.