Subscribe to the Non-Human & AI Identity Journal

What breaks when untrusted code runs inside a vm2 sandbox that relies on sanitization?

The boundary breaks when attacker-controlled code reaches host process capabilities through a sanitization bypass, because the sandbox shares the same Node.js process and inherits its privileges. At that point, the attacker can execute commands, inspect memory, or pivot into internal resources that were never meant to face untrusted input.

Why This Matters for Security Teams

vm2-style sandboxes are often treated as a safe way to run untrusted JavaScript, but sanitization is not a security boundary when the attacker can steer execution toward a bypass. Once code crosses from the sandbox into the host process, it inherits the Node.js runtime’s privileges, which turns a containment issue into full process compromise. That means command execution, filesystem access, memory exposure, and lateral movement into adjacent systems are all on the table.

This is especially dangerous when the sandbox is used to handle secrets, customer data, plugin logic, or AI-generated code paths. NHIMG research shows that 96% of organisations store secrets outside of secrets managers in vulnerable locations, including code and CI/CD tools, which makes a sandbox escape much more than a theoretical bug. The lesson aligns with the control intent behind NIST SP 800-53 Rev 5 Security and Privacy Controls: if untrusted input can touch privileged process state, the boundary is already too soft. In practice, many security teams discover this only after an escape is chained with exposed credentials or internal service reachability, rather than through intentional testing.

How It Works in Practice

vm2 relies on code transformation and sanitization to restrict what guest code can access, but that model depends on every dangerous path being perfectly filtered. In real deployments, attackers do not need a complete bypass on day one. They look for parser edge cases, prototype manipulation, exception handling quirks, or object-graph tricks that let them recover references to host objects. Once a host reference is available, the sandbox becomes irrelevant because the attacker is now executing with the same process context as the application.

That is why this pattern is so risky for systems that also handle secrets or internal credentials. NHIMG reporting on Code Formatting Tools Credential Leaks and Hard-Coded Secrets in VSCode Extensions shows the same operational pattern: once untrusted code runs in a privileged application context, secret exposure becomes a routine outcome, not an edge case.

Practitioners should assume the following protections are needed if untrusted code must run at all:

  • Use process isolation, not only in-process sanitization, when the code is adversarial.
  • Remove ambient privileges from the host process and run with the minimum OS permissions.
  • Keep secrets out of memory and out of the runtime environment whenever possible.
  • Treat outbound network access as controlled and explicit, not inherited by default.
  • Log escape attempts and policy violations, then terminate the workload rather than degrading gracefully.

These controls tend to break down in long-lived Node.js services with plugin ecosystems, shared memory state, or direct access to internal APIs because a single host reference can collapse the intended trust separation.

Common Variations and Edge Cases

Tighter isolation often increases latency and operational overhead, so teams have to balance developer convenience against the blast-radius reduction that true containment provides. Current guidance suggests that sanitization can still be useful as a defense-in-depth layer, but there is no universal standard for treating it as sufficient isolation for hostile code.

Edge cases matter. A sandbox that appears safe for small snippets may fail under recursive payloads, async control-flow abuse, or error-path exploitation. If the untrusted code only needs read-only data, the risk is lower, but once the same runtime can reach internal tokens, file handles, or network clients, the trust model collapses quickly. That is why mature programs pair containment with stronger application governance, as described in NHI Mgmt Group’s Ultimate Guide to Non-Human Identities, especially where ephemeral secrets, least privilege, and revocation discipline are already expected.

For agentic or automated code execution, the safest assumption is that any sanitization bypass is a full escape path. In practice, many teams only learn that lesson after an exploit chain has already turned a convenience sandbox into a host compromise.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP Non-Human Identity Top 10, OWASP Agentic AI Top 10 and CSA MAESTRO address the attack and risk surface, while NIST AI RMF and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
OWASP Non-Human Identity Top 10 NHI-01 Sanitization bypasses expose weak NHI isolation and trust boundaries.
OWASP Agentic AI Top 10 A-03 Untrusted autonomous code can pivot through tool and process access.
CSA MAESTRO M1 MAESTRO addresses runtime isolation and agent execution risk.
NIST AI RMF AI risk controls apply when model or plugin code can act on host resources.
NIST CSF 2.0 PR.AC-4 Least privilege is central when sandboxed code can reach privileged resources.

Separate untrusted workloads from host privileges and avoid sharing long-lived credentials with sandboxed code.