Safely Running Untrusted Code in Node.js: Isolation Strategies & Performance

This article examines reliable and relatively reliable methods for executing untrusted JavaScript code in Node.js, comparing new Function, the VM module, and Worker Threads, discussing their isolation levels, memory and CPU limits, performance overhead, and extending to container and WebAssembly security solutions.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
Safely Running Untrusted Code in Node.js: Isolation Strategies & Performance

What scenarios need code isolation?

Common cases include:

SSR (server‑side rendering) where component code must run on the server.

Distributed scheduled‑task systems that execute lightweight user‑submitted scripts.

Rule engines that evaluate matching conditions.

Problems to solve

Typical challenges are:

Memory leaks caused by insufficient variable isolation.

CPU‑time limits, e.g., infinite loops or long‑running code.

Control of external resources.

Node.js code execution model

Node.js runs on a single OS thread with a single V8 isolate by default. An isolate is an independent V8 instance that includes its own memory management and garbage collector, and it is bound to an OS thread.

A context is a global object defined on the heap of an isolate. Multiple contexts can exist within one isolate and can safely access each other.

Specific solutions

new Function

const func = new Function(`console.log('hello')`).bind({});

This approach is fast and scopes local variables to func, but it allows escaping to the global scope, e.g.:

const global = Function('return this')();
new Function('const global = Function("return this")(); return {global, a: this};').bind({})();

Node.js VM module

The VM module (available since Node.js 0.3.0) provides better variable isolation than new Function.

const vm = require('vm');
const script = new vm.Script('globalVar = "set"');
const contexts = [{}, {}, {}];
contexts.forEach(context => {
  script.runInNewContext(context);
});
console.log(contexts); // [{globalVar: 'set'}, {globalVar: 'set'}, {globalVar: 'set'}]

Creating a context is relatively slow, which can affect performance for frequently executed code.

Node.js Worker Threads

Worker Threads (introduced in Node.js 10.x) create separate isolates, enabling multi‑threaded execution. They can be combined with the VM module for full isolation, but thread creation is expensive and communication is limited to data structures supported by the HTML Structured Clone algorithm.

Comparison of solutions

Solution

Variable isolation

Memory limit

Isolated isolation

Execution time limit

Async operation limit

new Function

Partial

vm

worker threads

Extension: Security

None of the above solutions provide strong protection against malicious code. Two higher‑level approaches are recommended:

Trusted containers

Use trimmed virtual machine monitors (e.g., AWS Firecracker) to achieve isolation at the hypervisor level.

WebAssembly containers

Compile code to WebAssembly and run it in a WASI‑enabled container, allowing control over instruction speed, memory usage, and external resource access. Current limitations include immature tooling and limited V8 support for fine‑grained control.

Community projects such as isolated‑vm also explore isolate‑based isolation.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

WebAssemblyNode.jsvmSecuritycode isolationWorker Threads
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.