Skip to main content

Example on GitHub

Runnable example for network access control.
Network access is deny-by-default. Enable it by setting useDefaultNetwork: true on the system driver and granting the network permission.

Runnable example

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

const logs: string[] = [];

const runtime = new NodeRuntime({
	systemDriver: createNodeDriver({
		useDefaultNetwork: true,
		permissions: { ...allowAllNetwork },
	}),
	runtimeDriverFactory: createNodeRuntimeDriverFactory(),
});

try {
	const result = await runtime.exec(
		`
			(async () => {
				const http = require("node:http");

				const server = http.createServer((_req, res) => {
					res.writeHead(200, { "content-type": "text/plain" });
					res.end("network-ok");
				});

				await new Promise((resolve, reject) => {
					server.once("error", reject);
					server.listen(0, "127.0.0.1", resolve);
				});

				const address = server.address();
				if (!address || typeof address === "string") {
					throw new Error("missing loopback address");
				}

				const response = await fetch("http://127.0.0.1:" + address.port + "/");
				const body = await response.text();

				if (!response.ok || response.status !== 200 || body !== "network-ok") {
					throw new Error(
						"unexpected response: " + response.status + " " + body,
					);
				}

				console.log(JSON.stringify({ status: response.status, body }));

				await new Promise((resolve) => server.close(resolve));
			})().catch((error) => {
				console.error(error instanceof Error ? error.message : String(error));
				process.exitCode = 1;
			});
		`,
		{
			onStdio: (event) => {
				logs.push(`[${event.channel}] ${event.message}`);
			},
		},
	);

	if (result.code !== 0) {
		throw new Error(`Unexpected execution result: ${JSON.stringify(result)}`);
	}

	const payload = logs
		.filter((line) => line.startsWith("[stdout] "))
		.map((line) => line.slice("[stdout] ".length))
		.map((line) => JSON.parse(line))
		.at(-1);

	if (payload?.status !== 200 || payload?.body !== "network-ok") {
		throw new Error(`Unexpected captured output: ${JSON.stringify(logs)}`);
	}

	console.log(
		JSON.stringify({
			ok: true,
			status: payload.status,
			body: payload.body,
			summary: "sandbox started a loopback HTTP server and fetched it",
		}),
	);
} finally {
	runtime.dispose();
}
Source: examples/features/src/networking.ts

Quick setup

import { createNodeDriver, allowAllNetwork } from "secure-exec";

const driver = createNodeDriver({
  useDefaultNetwork: true,
  permissions: { ...allowAllNetwork },
});
The Node adapter supports fetch, DNS lookups, and low-level HTTP requests.

Network adapters

You can provide a custom adapter instead of using useDefaultNetwork:
import { createNodeDriver, createDefaultNetworkAdapter, allowAllNetwork } from "secure-exec";

const driver = createNodeDriver({
  networkAdapter: createDefaultNetworkAdapter(),
  permissions: { ...allowAllNetwork },
});
FactoryEnvironmentCapabilities
createDefaultNetworkAdapter()Nodefetch, DNS, HTTP
createBrowserNetworkAdapter()Browserfetch only

NetworkAdapter interface

MethodReturnsDescription
fetch(url, options?)Promise<FetchResponse>HTTP fetch
dnsLookup(hostname)Promise<DnsResult>DNS resolution
httpRequest(url, options?)Promise<HttpResponse>Low-level HTTP request
httpServerListen?(options)Promise<{ address }>Start a loopback HTTP server
httpServerClose?(serverId)Promise<void>Close a loopback HTTP server

Permission gating

Use a function to filter requests:
const driver = createNodeDriver({
  useDefaultNetwork: true,
  permissions: {
    network: (req) => {
      if (req.hostname?.endsWith(".internal")) {
        return { allow: false };
      }
      if (req.hostname === "169.254.169.254") {
        return { allow: false };
      }
      return { allow: true };
    },
  },
});