Skip to content

Harden VM context disable codegen and avoid leaking host console#1024

Open
thesmartshadow wants to merge 3 commits intovercel:mainfrom
thesmartshadow:fix/vm-hardening
Open

Harden VM context disable codegen and avoid leaking host console#1024
thesmartshadow wants to merge 3 commits intovercel:mainfrom
thesmartshadow:fix/vm-hardening

Conversation

@thesmartshadow
Copy link

Summary

This PR hardens the node:vm execution context used by Workflow by:

  • Disabling string-based code generation inside the VM realm (eval, new Function, etc.)
  • Disabling WebAssembly code generation inside the VM realm
  • Avoiding leaking the host console object into the VM by reference (provides a VM-local console stub)

Important: node:vm is not a security sandbox. This is a defense-in-depth change that reduces risky primitives and cross-realm object sharing when VM-executed code is attacker-controlled or partially untrusted.


Security severity (risk rating)

Recommended severity: Medium (Security Hardening / Defense-in-Depth)

Why not “Critical”?

  • If an attacker can run arbitrary JS in the VM already, they already have “code execution” inside the VM realm.
  • The risk here is policy bypass / attack-surface expansion / integrity impact, not a proven sandbox escape on its own.

Why still Medium?

  • Allowing runtime code generation (strings/wasm) + leaking host object references increases the chance of:
    • bypassing restrictions (present or future),
    • expanding escape primitives,
    • undermining observability/log integrity.

If your threat model includes attacker-controlled workflow code, this should be treated as a security-relevant hardening change.


Classification

Category: Security hardening / sandbox policy enforcement
Affected area: VM context creation and VM globals
Attack precondition: Attacker controls (or partially controls) code executed inside the VM realm
Impact: Attack-surface expansion + cross-realm mutation (integrity / observability)

CWE mapping (best-fit)

  • CWE-94: Improper Control of Generation of Code
    (runtime string codegen via eval / Function inside the VM realm)
  • CWE-668: Exposure of Resource to Wrong Sphere
    (host console object leaked to the VM by reference)
  • CWE-653: Insufficient Compartmentalization
    (VM realm receives references that should remain host-only)

Note: CWE selection here reflects the security property being enforced (no runtime codegen; no host references), not a claim of full sandboxing.


Root cause

  1. VM context allowed dynamic code generation

    • vm.createContext() was created without codeGeneration restrictions.
    • VM code could compile new code at runtime via:
      • eval("...")
      • new Function("...")
      • WebAssembly compilation (where supported)
  2. Host console leaked into VM by reference

    • vmGlobalThis.console = globalThis.console
    • This gives VM code a direct handle to a host object and allows cross-realm mutation
      (at minimum affecting logging/telemetry integrity and developer expectations).

Fix

A) Disable VM code generation

Create the VM context with:

  • codeGeneration.strings = false
  • codeGeneration.wasm = false

This blocks common runtime compilation primitives inside the VM realm.

B) Avoid leaking host console references

Instead of assigning globalThis.console into the VM realm, provide a VM-local console stub.


Proof / PoC (before vs after)

This PR includes a focused regression suite:
packages/core/src/vm/vm-hardening.test.ts

Screenshot From 2026-02-12 18-09-46

1) PoC: block eval and new Function

Before: VM realm can evaluate string code generation
After: VM realm throws (codegen blocked)

Conceptually:

// inside VM realm
eval("1+1");
(new Function("return 2+2"))();

Expected behavior:

  • Before this PR: succeeds
  • After this PR: throws (blocked by VM codeGeneration policy)

2) PoC: prevent host console mutation (cross-realm reference leak)

Before: VM can mutate host console methods by reference
After: VM uses a VM-local console stub, so host console remains untouched

Conceptually:

// VM mutates console
console.log = () => "pwned";

// host now impacted if the host console was leaked by reference

Expected behavior:

  • Before this PR: host console can be affected
  • After this PR: host console is not a reachable reference from the VM realm

Test plan

Core build + full test run:

pnpm --filter @workflow/core build
pnpm --filter @workflow/core test

(Optional) Run only the hardening suite:

pnpm --filter @workflow/core test -- src/vm/vm-hardening.test.ts

Notes / rationale

  • This change intentionally reduces risky primitives available to untrusted VM code.
  • It improves future maintainability: policy expectations are explicit (no runtime codegen; no host references).
  • It does not claim node:vm is a sandbox only that these specific primitives are now constrained.

@changeset-bot
Copy link

changeset-bot bot commented Feb 12, 2026

🦋 Changeset detected

Latest commit: 28da161

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@workflow/core Patch
@workflow/builders Patch
@workflow/cli Patch
@workflow/next Patch
@workflow/nitro Patch
@workflow/web-shared Patch
workflow Patch
@workflow/astro Patch
@workflow/nest Patch
@workflow/rollup Patch
@workflow/sveltekit Patch
@workflow/vite Patch
@workflow/world-testing Patch
@workflow/nuxt Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Contributor

vercel bot commented Feb 12, 2026

@thesmartshadow is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

Signed-off-by: thesmartshadow <firaswq12@gmail.com>
I, thesmartshadow <firaswq12@gmail.com>, hereby add my Signed-off-by to this commit: 8a8e4e5
I, thesmartshadow <firaswq12@gmail.com>, hereby add my Signed-off-by to this commit: 24aca63

Signed-off-by: thesmartshadow <firaswq12@gmail.com>
@i5d6
Copy link

i5d6 commented Feb 13, 2026

Good Job allawi :*

@thesmartshadow
Copy link
Author

Good Job allawi :*

Good Job, Allawi 😄
You really put in that work, bro I’m proud of you fr.
I’d be happy to team up and build something together.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants