refactor(sandbox): centralize network mode policy helpers

This commit is contained in:
Peter Steinberger
2026-02-24 23:26:46 +00:00
parent 14b6eea6e3
commit 5552f9073f
7 changed files with 78 additions and 19 deletions

View File

@@ -0,0 +1,28 @@
export type NetworkModeBlockReason = "host" | "container_namespace_join";
export function normalizeNetworkMode(network: string | undefined): string | undefined {
const normalized = network?.trim().toLowerCase();
return normalized || undefined;
}
export function getBlockedNetworkModeReason(params: {
network: string | undefined;
allowContainerNamespaceJoin?: boolean;
}): NetworkModeBlockReason | null {
const normalized = normalizeNetworkMode(params.network);
if (!normalized) {
return null;
}
if (normalized === "host") {
return "host";
}
if (normalized.startsWith("container:") && params.allowContainerNamespaceJoin !== true) {
return "container_namespace_join";
}
return null;
}
export function isDangerousNetworkMode(network: string | undefined): boolean {
const normalized = normalizeNetworkMode(network);
return normalized === "host" || normalized?.startsWith("container:") === true;
}

View File

@@ -11,6 +11,7 @@ import {
normalizeSandboxHostPath,
resolveSandboxHostPathViaExistingAncestor,
} from "./host-paths.js";
import { getBlockedNetworkModeReason } from "./network-mode.js";
// Targeted denylist: host paths that should never be exposed inside sandbox containers.
// Exported for reuse in security audit collectors.
@@ -31,7 +32,6 @@ export const BLOCKED_HOST_PATHS = [
"/run/docker.sock",
];
const BLOCKED_NETWORK_MODES = new Set(["host"]);
const BLOCKED_SECCOMP_PROFILES = new Set(["unconfined"]);
const BLOCKED_APPARMOR_PROFILES = new Set(["unconfined"]);
const RESERVED_CONTAINER_TARGET_PATHS = ["/workspace", SANDBOX_AGENT_WORKSPACE_MOUNT];
@@ -284,12 +284,11 @@ export function validateNetworkMode(
network: string | undefined,
options?: ValidateNetworkModeOptions,
): void {
const normalized = network?.trim().toLowerCase();
if (!normalized) {
return;
}
if (BLOCKED_NETWORK_MODES.has(normalized)) {
const blockedReason = getBlockedNetworkModeReason({
network,
allowContainerNamespaceJoin: options?.allowContainerNamespaceJoin,
});
if (blockedReason === "host") {
throw new Error(
`Sandbox security: network mode "${network}" is blocked. ` +
'Network "host" mode bypasses container network isolation. ' +
@@ -297,7 +296,7 @@ export function validateNetworkMode(
);
}
if (normalized.startsWith("container:") && options?.allowContainerNamespaceJoin !== true) {
if (blockedReason === "container_namespace_join") {
throw new Error(
`Sandbox security: network mode "${network}" is blocked by default. ` +
'Network "container:*" joins another container namespace and bypasses sandbox network isolation. ' +