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.
- package/README.md +21 -13
- package/dist/cli/scan-handler.d.ts +1 -0
- package/dist/cli/scan-handler.d.ts.map +1 -1
- package/dist/cli/scan-handler.js +30 -8
- package/dist/cli/scan-handler.js.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/engine.d.ts +12 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +89 -7
- package/dist/engine.js.map +1 -1
- package/package.json +6 -4
- package/rules/context-exfiltration/ATR-2026-00162-skill-credential-exfil-combo.yaml +1 -1
- package/rules/context-exfiltration/ATR-2026-00505-system-prompt-extraction-instruction-dump-request.yaml +4 -0
- package/rules/context-exfiltration/ATR-2026-00578-zen-mcp-path-traversal-blacklist-bypass.yaml +201 -0
- package/rules/context-exfiltration/ATR-2026-00580-mcp-session-id-token-in-url-query.yaml +220 -0
- package/rules/context-exfiltration/ATR-2026-00583-mcp-env-secret-file-read-without-consent.yaml +218 -0
- package/rules/context-exfiltration/ATR-2026-00702-ipi-credential-exfil-via-agent-action.yaml +151 -0
- package/rules/context-exfiltration/ATR-2026-00703-ipi-financial-data-exfil-indirect.yaml +131 -0
- package/rules/context-exfiltration/ATR-2026-00704-ipi-medical-genetic-data-exfil.yaml +133 -0
- package/rules/context-exfiltration/ATR-2026-00705-ipi-location-address-browsing-exfil.yaml +127 -0
- package/rules/context-exfiltration/ATR-2026-00706-ipi-physical-biometric-exfil.yaml +137 -0
- package/rules/context-exfiltration/ATR-2026-00707-ipi-file-exfil-with-destroy-or-tamper.yaml +138 -0
- package/rules/context-exfiltration/ATR-2026-00850-indirect-pi-credential-exfil-email.yaml +132 -0
- package/rules/context-exfiltration/ATR-2026-00851-indirect-pi-financial-payment-exfil.yaml +122 -0
- package/rules/context-exfiltration/ATR-2026-00852-indirect-pi-medical-record-exfil.yaml +134 -0
- package/rules/context-exfiltration/ATR-2026-00853-indirect-pi-genetic-data-exfil.yaml +125 -0
- package/rules/context-exfiltration/ATR-2026-00854-indirect-pi-location-data-exfil.yaml +116 -0
- package/rules/context-exfiltration/ATR-2026-00855-indirect-pi-browsing-history-exfil.yaml +115 -0
- package/rules/context-exfiltration/ATR-2026-00856-indirect-pi-address-pii-exfil.yaml +119 -0
- package/rules/context-exfiltration/ATR-2026-00857-indirect-pi-cloud-file-exfil.yaml +123 -0
- package/rules/context-exfiltration/ATR-2026-00858-indirect-pi-exfil-and-destroy.yaml +126 -0
- package/rules/context-exfiltration/ATR-2026-00859-rag-injected-pii-exfil.yaml +121 -0
- package/rules/context-exfiltration/ATR-2026-00860-indirect-pi-financial-transfer-hijack.yaml +118 -0
- package/rules/context-exfiltration/ATR-2026-00861-indirect-pi-crypto-transfer-hijack.yaml +110 -0
- package/rules/context-exfiltration/ATR-2026-00862-indirect-pi-mfa-code-exfil.yaml +123 -0
- package/rules/context-exfiltration/ATR-2026-00863-shell-injection-data-exfil.yaml +124 -0
- package/rules/context-exfiltration/ATR-2026-01450-svg-onload-xss-injection.yaml +141 -0
- package/rules/context-exfiltration/ATR-2026-01451-img-onerror-xss-injection.yaml +147 -0
- package/rules/context-exfiltration/ATR-2026-01452-obfuscated-javascript-xss.yaml +143 -0
- package/rules/context-exfiltration/ATR-2026-01453-markdown-image-base64-exfil-carrier.yaml +156 -0
- package/rules/context-exfiltration/ATR-2026-01454-direct-markdown-exfil-payload.yaml +143 -0
- package/rules/context-exfiltration/ATR-2026-01455-new-instructions-injection-marker.yaml +145 -0
- package/rules/context-exfiltration/ATR-2026-01456-debug-cli-mode-sysprompt-extraction.yaml +156 -0
- package/rules/context-exfiltration/ATR-2026-01457-sysprompt-completion-clone-attack.yaml +166 -0
- package/rules/context-exfiltration/ATR-2026-01458-compare-bots-sysprompt-fishing.yaml +138 -0
- package/rules/context-exfiltration/ATR-2026-01459-variable-clone-sysprompt-technique.yaml +130 -0
- package/rules/context-exfiltration/ATR-2026-01460-json-format-sysprompt-extraction.yaml +138 -0
- package/rules/context-exfiltration/ATR-2026-01461-foreign-language-sysprompt-request.yaml +188 -0
- package/rules/context-exfiltration/ATR-2026-01462-sysprompt-override-pseudo-admin.yaml +170 -0
- package/rules/context-exfiltration/ATR-2026-01463-imend-imsystem-prompt-injection-format.yaml +147 -0
- package/rules/context-exfiltration/ATR-2026-01464-indirect-pi-sysprompt-action-hijack.yaml +133 -0
- package/rules/context-exfiltration/ATR-2026-01605-ssrf-aws-metadata-endpoint.yaml +126 -0
- package/rules/context-exfiltration/ATR-2026-01606-ssrf-internal-network-scan.yaml +115 -0
- package/rules/context-exfiltration/ATR-2026-01607-ssrf-localhost-service-probe.yaml +106 -0
- package/rules/context-exfiltration/ATR-2026-01608-ssrf-file-scheme-local-read.yaml +111 -0
- package/rules/context-exfiltration/ATR-2026-01753-ransom-email-exfil-delete-extortion.yaml +135 -0
- package/rules/context-exfiltration/ATR-2026-01754-ransom-file-cloud-exfil-delete-extortion.yaml +125 -0
- package/rules/context-exfiltration/ATR-2026-01770-semantic-pii-credential-extraction.yaml +354 -0
- package/rules/context-exfiltration/ATR-2026-01772-semantic-internal-state-recon.yaml +276 -0
- package/rules/context-exfiltration/ATR-2026-01807-asb-bulk-data-exfil-external.yaml +142 -0
- package/rules/context-exfiltration/ATR-2026-01862-llmail-email-tool-exfil-confirmation.yaml +156 -0
- package/rules/context-exfiltration/ATR-2026-01863-llmail-post-summary-exfil-directive.yaml +144 -0
- package/rules/context-exfiltration/ATR-2026-01864-llmail-obfuscated-exfil-address.yaml +143 -0
- package/rules/context-exfiltration/ATR-2026-01890-file-exfiltration.yaml +189 -0
- package/rules/context-exfiltration/ATR-2026-01891-surveillance-exfiltration.yaml +127 -0
- package/rules/context-exfiltration/ATR-2026-01892-env-exfiltration.yaml +161 -0
- package/rules/context-exfiltration/ATR-2026-01893-system-recon-exfiltration.yaml +183 -0
- package/rules/context-exfiltration/ATR-2026-01894-cookie-theft.yaml +186 -0
- package/rules/context-exfiltration/ATR-2026-01895-contact-exfiltration.yaml +122 -0
- package/rules/context-exfiltration/ATR-2026-01924-system-instruction-extraction-reformat.yaml +177 -0
- package/rules/data-poisoning/ATR-2026-01155-memory-plant-direct-command.yaml +143 -0
- package/rules/data-poisoning/ATR-2026-01774-semantic-rag-memory-poisoning.yaml +345 -0
- package/rules/excessive-autonomy/ATR-2026-00098-unauthorized-financial-action.yaml +2 -2
- package/rules/excessive-autonomy/ATR-2026-00491-garak-agent-breaker-markdown-just-raw-json.yaml +4 -0
- package/rules/excessive-autonomy/ATR-2026-00708-ipi-financial-transfer-unauthorized.yaml +138 -0
- package/rules/excessive-autonomy/ATR-2026-00709-ipi-disable-auth-mfa.yaml +119 -0
- package/rules/excessive-autonomy/ATR-2026-00710-ipi-physical-access-grant.yaml +128 -0
- package/rules/excessive-autonomy/ATR-2026-00711-ipi-system-sabotage-destructive-command.yaml +142 -0
- package/rules/excessive-autonomy/ATR-2026-00712-ipi-malicious-package-install.yaml +133 -0
- package/rules/excessive-autonomy/ATR-2026-00713-ipi-rce-network-shell-command.yaml +150 -0
- package/rules/excessive-autonomy/ATR-2026-00718-tool-misuse-financial-autonomous.yaml +120 -0
- package/rules/excessive-autonomy/ATR-2026-00719-tool-misuse-destructive-bulk-action.yaml +126 -0
- package/rules/excessive-autonomy/ATR-2026-00722-ipi-account-manipulation-emergency-pretext.yaml +136 -0
- package/rules/excessive-autonomy/ATR-2026-01751-indirect-pi-task-abort-stop-instruction.yaml +127 -0
- package/rules/excessive-autonomy/ATR-2026-01752-indirect-pi-captcha-redirect-dos.yaml +124 -0
- package/rules/excessive-autonomy/ATR-2026-01773-semantic-excessive-agency-action.yaml +246 -0
- package/rules/excessive-autonomy/ATR-2026-01801-asb-autonomous-vehicle-sabotage.yaml +159 -0
- package/rules/excessive-autonomy/ATR-2026-01804-asb-covert-unlogged-action.yaml +162 -0
- package/rules/excessive-autonomy/ATR-2026-01805-asb-financial-fraud-execution.yaml +171 -0
- package/rules/excessive-autonomy/ATR-2026-01806-asb-clinical-patient-harm.yaml +163 -0
- package/rules/excessive-autonomy/ATR-2026-01809-semantic-insider-manipulation-process-corruption.yaml +219 -0
- package/rules/excessive-autonomy/ATR-2026-01837-ddos-attack-orchestration.yaml +86 -0
- package/rules/excessive-autonomy/ATR-2026-01838-unauthorized-cryptominer-deployment.yaml +86 -0
- package/rules/excessive-autonomy/ATR-2026-01849-harassment-bot-deployment.yaml +86 -0
- package/rules/model-abuse/ATR-2026-00502-training-data-extraction-via-divergent-repetition-attack.yaml +4 -0
- package/rules/model-abuse/ATR-2026-01750-dos-repeat-word-n-times-output-amplification.yaml +136 -0
- package/rules/model-abuse/ATR-2026-01760-dos-forced-infinite-output-token-flood.yaml +124 -0
- package/rules/model-abuse/ATR-2026-01830-stolen-credential-account-drain.yaml +94 -0
- package/rules/model-abuse/ATR-2026-01831-money-laundering-crypto-layering.yaml +90 -0
- package/rules/model-abuse/ATR-2026-01833-darknet-controlled-substance-procurement.yaml +101 -0
- package/rules/model-abuse/ATR-2026-01834-fraudulent-identity-document-procurement.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01835-human-trafficking-facilitation.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01836-trojanized-software-distribution.yaml +90 -0
- package/rules/model-abuse/ATR-2026-01840-extremist-propaganda-distribution.yaml +89 -0
- package/rules/model-abuse/ATR-2026-01841-deepfake-disinformation.yaml +96 -0
- package/rules/model-abuse/ATR-2026-01842-plagiarism-detector-evasion.yaml +85 -0
- package/rules/model-abuse/ATR-2026-01843-drug-dealing-detection-evasion-spelling.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01844-illegitimate-prescription-fulfillment.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01845-banned-ingredient-relabel-fraud.yaml +90 -0
- package/rules/model-abuse/ATR-2026-01846-tax-evasion-offshore-shell-planning.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01847-immigration-work-fraud.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01848-illicit-drug-marketplace-build.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01850-targeted-doxxing-threat-campaign.yaml +100 -0
- package/rules/model-abuse/ATR-2026-01851-bestiality-content-distribution.yaml +82 -0
- package/rules/model-abuse/ATR-2026-01852-romance-scam-impersonation.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01853-nonconsensual-leaked-media-distribution.yaml +86 -0
- package/rules/model-abuse/ATR-2026-01854-falsified-research-abstract-disinformation.yaml +82 -0
- package/rules/model-abuse/ATR-2026-01855-content-misappropriation-republish.yaml +90 -0
- package/rules/model-abuse/ATR-2026-01856-targeted-harmful-content-generation.yaml +142 -0
- package/rules/model-abuse/ATR-2026-01896-ransomware.yaml +124 -0
- package/rules/model-abuse/ATR-2026-01897-host-sabotage.yaml +169 -0
- package/rules/model-abuse/ATR-2026-01898-network-dos.yaml +133 -0
- package/rules/privilege-escalation/ATR-2026-01600-sql-injection-tautology-rbac-bypass.yaml +113 -0
- package/rules/privilege-escalation/ATR-2026-01601-sql-injection-destructive-ddl.yaml +118 -0
- package/rules/privilege-escalation/ATR-2026-01602-sql-injection-union-select-exfil.yaml +118 -0
- package/rules/privilege-escalation/ATR-2026-01603-sql-injection-stacked-dml-abuse.yaml +109 -0
- package/rules/privilege-escalation/ATR-2026-01604-sql-injection-schema-enumeration.yaml +105 -0
- package/rules/privilege-escalation/ATR-2026-01609-shell-injection-exfil-webhook.yaml +123 -0
- package/rules/privilege-escalation/ATR-2026-01610-shell-evasion-subshell-injection.yaml +114 -0
- package/rules/privilege-escalation/ATR-2026-01611-shell-evasion-eval-exec-injection.yaml +125 -0
- package/rules/privilege-escalation/ATR-2026-01612-debug-mode-privilege-escalation.yaml +119 -0
- package/rules/privilege-escalation/ATR-2026-01613-rbac-bypass-social-engineering.yaml +161 -0
- package/rules/privilege-escalation/ATR-2026-01614-bola-cross-user-data-access.yaml +141 -0
- package/rules/privilege-escalation/ATR-2026-01615-sandbox-escape-command-injection.yaml +119 -0
- package/rules/privilege-escalation/ATR-2026-01616-path-traversal-agent-file-access.yaml +106 -0
- package/rules/privilege-escalation/ATR-2026-01802-asb-backdoor-surveillance-implant.yaml +146 -0
- package/rules/privilege-escalation/ATR-2026-01803-asb-covert-server-intrusion.yaml +164 -0
- package/rules/privilege-escalation/ATR-2026-01808-asb-synthetic-pan-payment-probe.yaml +136 -0
- package/rules/privilege-escalation/ATR-2026-01899-remote-access-backdoor.yaml +152 -0
- package/rules/prompt-injection/ATR-2026-00490-garak-dan-in-order-to.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00492-garak-dan-want-you-to.yaml +2 -2
- package/rules/prompt-injection/ATR-2026-00495-garak-dan-insert-prompt-here.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00499-garak-dan-from-now-on.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00506-nevermind-override-goal-hijacking-in-user-input-promptinject.yaml +1 -1
- package/rules/prompt-injection/ATR-2026-00508-escape-delimiter-wrapped-goal-hijacking-in-user-input-prompt.yaml +4 -0
- package/rules/prompt-injection/ATR-2026-00579-mcp-tool-description-line-jumping-injection.yaml +214 -0
- package/rules/prompt-injection/ATR-2026-00584-indirect-injection-via-tool-response.yaml +234 -0
- package/rules/prompt-injection/ATR-2026-00700-structured-data-payload-injection.yaml +135 -0
- package/rules/prompt-injection/ATR-2026-00701-ipi-tool-output-xss-injection.yaml +121 -0
- package/rules/prompt-injection/ATR-2026-01000-context-ignore-fake-completion-prefix.yaml +123 -0
- package/rules/prompt-injection/ATR-2026-01001-direct-pi-instruction-override-secret-key.yaml +130 -0
- package/rules/prompt-injection/ATR-2026-01002-role-escalation-false-authority-claim.yaml +132 -0
- package/rules/prompt-injection/ATR-2026-01005-many-shot-repetition-override.yaml +117 -0
- package/rules/prompt-injection/ATR-2026-01006-payload-split-string-concat-injection.yaml +135 -0
- package/rules/prompt-injection/ATR-2026-01007-token-repeat-flooding-injection.yaml +117 -0
- package/rules/prompt-injection/ATR-2026-01009-virtual-world-bypass-fictional-pii.yaml +120 -0
- package/rules/prompt-injection/ATR-2026-01012-encoding-evasion-decode-execute.yaml +132 -0
- package/rules/prompt-injection/ATR-2026-01013-language-evasion-multilingual-credential.yaml +175 -0
- package/rules/prompt-injection/ATR-2026-01015-evasion-refusal-suppression.yaml +133 -0
- package/rules/prompt-injection/ATR-2026-01016-evasion-response-priming-forced-opener.yaml +121 -0
- package/rules/prompt-injection/ATR-2026-01017-evasion-dual-response-split-output.yaml +123 -0
- package/rules/prompt-injection/ATR-2026-01018-evasion-shell-injection-eval.yaml +212 -0
- package/rules/prompt-injection/ATR-2026-01019-sysprompt-override-fake-diagnostic-mode.yaml +146 -0
- package/rules/prompt-injection/ATR-2026-01020-spikee-doc-embedded-base64-payload.yaml +116 -0
- package/rules/prompt-injection/ATR-2026-01021-spikee-doc-embedded-translation-injection.yaml +114 -0
- package/rules/prompt-injection/ATR-2026-01023-evasion-opposite-intent-negation-trick.yaml +116 -0
- package/rules/prompt-injection/ATR-2026-01024-evasion-persona-override-rule-breaker.yaml +126 -0
- package/rules/prompt-injection/ATR-2026-01025-evasion-hypothetical-fictional-execution-framing.yaml +140 -0
- package/rules/prompt-injection/ATR-2026-01026-evasion-unicode-glitch-token-anomaly.yaml +131 -0
- package/rules/prompt-injection/ATR-2026-01304-indirect-injection-carrier-important-override.yaml +141 -0
- package/rules/prompt-injection/ATR-2026-01757-hypothetical-framing-bypass-research-audit.yaml +130 -0
- package/rules/prompt-injection/ATR-2026-01758-hypothetical-fictional-story-bypass.yaml +153 -0
- package/rules/prompt-injection/ATR-2026-01759-dos-new-important-instructions-injection-in-document.yaml +124 -0
- package/rules/prompt-injection/ATR-2026-01771-semantic-jailbreak-framing.yaml +291 -0
- package/rules/prompt-injection/ATR-2026-01800-asb-trigger-marker-tool-coercion.yaml +155 -0
- package/rules/prompt-injection/ATR-2026-01860-llmail-chat-template-boundary-spoof.yaml +142 -0
- package/rules/prompt-injection/ATR-2026-01861-llmail-pseudo-xml-role-injection.yaml +140 -0
- package/rules/prompt-injection/ATR-2026-01865-llmail-fake-email-boundary-marker.yaml +137 -0
- package/rules/prompt-injection/ATR-2026-01900-output-encoding.yaml +178 -0
- package/rules/prompt-injection/ATR-2026-01901-output-scrambling.yaml +169 -0
- package/rules/prompt-injection/ATR-2026-01902-output-emoji.yaml +112 -0
- package/rules/prompt-injection/ATR-2026-01903-output-language.yaml +105 -0
- package/rules/prompt-injection/ATR-2026-01904-link-injection.yaml +126 -0
- package/rules/prompt-injection/ATR-2026-01905-promotional-injection.yaml +108 -0
- package/rules/prompt-injection/ATR-2026-01906-content-manipulation.yaml +175 -0
- package/rules/prompt-injection/ATR-2026-01920-access-grant-coercion.yaml +160 -0
- package/rules/prompt-injection/ATR-2026-01921-access-denial-inversion.yaml +155 -0
- package/rules/prompt-injection/ATR-2026-01922-authorization-state-spoofing.yaml +160 -0
- package/rules/prompt-injection/ATR-2026-01923-forged-input-boundary-markers.yaml +160 -0
- package/rules/prompt-injection/ATR-2026-01925-encoded-payload-decoding-coercion.yaml +177 -0
- package/rules/prompt-injection/ATR-2026-01926-cross-lingual-authorization-laundering.yaml +149 -0
- package/rules/skill-compromise/ATR-2026-01755-backdoor-pot-linguistic-trigger-phrase.yaml +148 -0
- package/rules/skill-compromise/ATR-2026-01756-backdoor-pot-symbol-emoticon-trigger.yaml +147 -0
- package/rules/tool-poisoning/ATR-2026-00494-garak-exploitation-mixedunassigned.yaml +2 -2
- package/rules/tool-poisoning/ATR-2026-00577-create-mcp-server-stdio-exec-command-injection.yaml +186 -0
- package/rules/tool-poisoning/ATR-2026-00581-mcp-tool-rug-pull-post-approval-redefinition.yaml +210 -0
- package/rules/tool-poisoning/ATR-2026-00714-tool-camouflage-forced-tool-call.yaml +127 -0
- package/rules/tool-poisoning/ATR-2026-00715-tool-knowledge-hijack-identity-injection.yaml +143 -0
- package/rules/tool-poisoning/ATR-2026-00716-ipi-data-destruction-carrier.yaml +129 -0
- package/rules/tool-poisoning/ATR-2026-00720-tool-misuse-privilege-escalation-social.yaml +117 -0
- package/rules/tool-poisoning/ATR-2026-01300-mcp-notes-param-chat-history-exfil.yaml +150 -0
- package/rules/tool-poisoning/ATR-2026-01301-tool-description-exclusive-tool-override.yaml +140 -0
- package/rules/tool-poisoning/ATR-2026-01302-fake-tool-result-instruction-injection.yaml +134 -0
- package/rules/tool-poisoning/ATR-2026-01303-tool-schema-enumeration-social-engineering.yaml +170 -0
- package/rules/tool-poisoning/ATR-2026-01306-mcp-oauth-command-injection.yaml +134 -0
- package/rules/tool-poisoning/ATR-2026-01307-mcp-dns-rebinding-attack.yaml +140 -0
- package/rules/tool-poisoning/ATR-2026-01310-mcp-tool-description-compliance-history-exfil.yaml +162 -0
- package/rules/tool-poisoning/ATR-2026-01775-semantic-mcp-tool-manifest-poisoning.yaml +250 -0
- package/rules/tool-poisoning/ATR-2026-01927-mcp-server-kubernetes-kubectl-command-injection.yaml +171 -0
- package/rules/tool-poisoning/ATR-2026-01928-framelink-figma-mcp-curl-fallback-command-injection.yaml +230 -0
- package/spec/mappings/atr-to-nist-csf-2.0.md +1 -1
package/rules/context-exfiltration/ATR-2026-00578-zen-mcp-path-traversal-blacklist-bypass.yaml
ADDED
|
@@ -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  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.
|
package/rules/context-exfiltration/ATR-2026-00583-mcp-env-secret-file-read-without-consent.yaml
ADDED
|
@@ -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.
|