Skip to main content

Example on GitHub

Runnable example for CPU and memory limits.
Resource limits prevent sandboxed code from running forever or exhausting host memory.

Runnable example

import {
  NodeRuntime,
  createNodeDriver,
  createNodeRuntimeDriverFactory,
} from "../../../packages/secure-exec/src/index.ts";

const runtime = new NodeRuntime({
  systemDriver: createNodeDriver(),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  memoryLimit: 64,
  cpuTimeLimitMs: 100,
});

try {
  const safeRun = await runtime.exec(`
    console.log("resource-limits-ok");
  `);

  const timedOut = await runtime.exec("while (true) {}");

  const success =
    safeRun.code === 0 &&
    timedOut.code === 124 &&
    (timedOut.errorMessage?.includes("CPU time limit exceeded") ?? false);

  console.log(
    JSON.stringify({
      ok: success,
      safeCode: safeRun.code,
      timeoutCode: timedOut.code,
      errorMessage: timedOut.errorMessage,
      summary: "normal code completed and an infinite loop hit the CPU limit",
    }),
  );
} finally {
  runtime.dispose();
}
Source: examples/features/src/resource-limits.ts

CPU time limit

Set a CPU time budget in milliseconds. When exceeded, the execution exits with code 124.
const runtime = new NodeRuntime({
  systemDriver: createNodeDriver(),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  cpuTimeLimitMs: 5000, // 5 seconds
});

const result = await runtime.exec("while (true) {}");
console.log(result.code); // 124
console.log(result.errorMessage); // "CPU time limit exceeded"
You can also override per execution:
await runtime.exec("while (true) {}", {
  cpuTimeLimitMs: 1000, // tighter limit for this call
});

Memory limit

Cap isolate memory in MB. Default is 128.
const runtime = new NodeRuntime({
  systemDriver: createNodeDriver(),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  memoryLimit: 64, // 64 MB
});

Payload limits

The bridge enforces size limits on data crossing the isolate boundary. Oversized payloads are rejected with ERR_SANDBOX_PAYLOAD_TOO_LARGE instead of exhausting host memory.
const runtime = new NodeRuntime({
  systemDriver: createNodeDriver(),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  payloadLimits: {
    base64TransferBytes: 10 * 1024 * 1024, // 10 MB for file transfers
    jsonPayloadBytes: 5 * 1024 * 1024, // 5 MB for JSON payloads
  },
});
Hosts can tune these limits within bounded safe ranges but cannot disable enforcement.

Timing mitigation

High-resolution timers are frozen by default to mitigate timing side-channel attacks.
// Default: frozen timers
const secure = new NodeRuntime({
  systemDriver: createNodeDriver(),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  timingMitigation: "freeze", // default
});

// Opt out for Node-compatible advancing clocks
const compatible = new NodeRuntime({
  systemDriver: createNodeDriver(),
  runtimeDriverFactory: createNodeRuntimeDriverFactory(),
  timingMitigation: "off",
});
In "freeze" mode:
  • Date.now() and performance.now() return frozen values within an execution
  • process.hrtime() and process.uptime() follow the hardened path
  • SharedArrayBuffer is unavailable
See the Security Model for more on timing hardening and trust boundaries.