VYPR
Low severityOSV Advisory· Published Dec 4, 2025· Updated Apr 15, 2026

CVE-2025-66479

CVE-2025-66479

Description

Anthropic Sandbox Runtime is a lightweight sandboxing tool for enforcing filesystem and network restrictions on arbitrary processes at the OS level, without requiring a container. Prior to 0.0.16, due to a bug in sandboxing logic, sandbox-runtime did not properly enforce a network sandbox if the sandbox policy did not configure any allowed domains. This could allow sandboxed code to make network requests outside of the sandbox. A patch for this was released in v0.0.16.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@anthropic-ai/sandbox-runtimenpm
< 0.0.160.0.16

Affected products

1

Patches

1
bea2930cc1db

Fix empty allowedDomains to block network as documented

4 files changed · +646 61
  • src/sandbox/linux-sandbox-utils.ts+52 51 modified
    @@ -568,65 +568,66 @@ export async function wrapCommandWithSandboxLinux(
     
         // ========== NETWORK RESTRICTIONS ==========
         if (needsNetworkRestriction) {
    -      // Only sandbox if we have network config and Linux bridges
    -      if (!httpSocketPath || !socksSocketPath) {
    -        throw new Error(
    -          'Linux network sandboxing was requested but bridge socket paths are not available',
    -        )
    -      }
    -
    -      // Verify socket files still exist before trying to bind them
    -      if (!fs.existsSync(httpSocketPath)) {
    -        throw new Error(
    -          `Linux HTTP bridge socket does not exist: ${httpSocketPath}. ` +
    -            'The bridge process may have died. Try reinitializing the sandbox.',
    -        )
    -      }
    -      if (!fs.existsSync(socksSocketPath)) {
    -        throw new Error(
    -          `Linux SOCKS bridge socket does not exist: ${socksSocketPath}. ` +
    -            'The bridge process may have died. Try reinitializing the sandbox.',
    -        )
    -      }
    -
    +      // Always unshare network namespace to isolate network access
    +      // This removes all network interfaces, effectively blocking all network
           bwrapArgs.push('--unshare-net')
     
    -      // Bind both sockets into the sandbox
    -      bwrapArgs.push('--bind', httpSocketPath, httpSocketPath)
    -      bwrapArgs.push('--bind', socksSocketPath, socksSocketPath)
    +      // If proxy sockets are provided, bind them into the sandbox to allow
    +      // filtered network access through the proxy. If not provided, network
    +      // is completely blocked (empty allowedDomains = block all)
    +      if (httpSocketPath && socksSocketPath) {
    +        // Verify socket files still exist before trying to bind them
    +        if (!fs.existsSync(httpSocketPath)) {
    +          throw new Error(
    +            `Linux HTTP bridge socket does not exist: ${httpSocketPath}. ` +
    +              'The bridge process may have died. Try reinitializing the sandbox.',
    +          )
    +        }
    +        if (!fs.existsSync(socksSocketPath)) {
    +          throw new Error(
    +            `Linux SOCKS bridge socket does not exist: ${socksSocketPath}. ` +
    +              'The bridge process may have died. Try reinitializing the sandbox.',
    +          )
    +        }
     
    -      // Add proxy environment variables
    -      // HTTP_PROXY points to the socat listener inside the sandbox (port 3128)
    -      // which forwards to the Unix socket that bridges to the host's proxy server
    -      const proxyEnv = generateProxyEnvVars(
    -        3128, // Internal HTTP listener port
    -        1080, // Internal SOCKS listener port
    -      )
    -      bwrapArgs.push(
    -        ...proxyEnv.flatMap((env: string) => {
    -          const firstEq = env.indexOf('=')
    -          const key = env.slice(0, firstEq)
    -          const value = env.slice(firstEq + 1)
    -          return ['--setenv', key, value]
    -        }),
    -      )
    +        // Bind both sockets into the sandbox
    +        bwrapArgs.push('--bind', httpSocketPath, httpSocketPath)
    +        bwrapArgs.push('--bind', socksSocketPath, socksSocketPath)
     
    -      // Add host proxy port environment variables for debugging/transparency
    -      // These show which host ports the Unix socket bridges connect to
    -      if (httpProxyPort !== undefined) {
    -        bwrapArgs.push(
    -          '--setenv',
    -          'CLAUDE_CODE_HOST_HTTP_PROXY_PORT',
    -          String(httpProxyPort),
    +        // Add proxy environment variables
    +        // HTTP_PROXY points to the socat listener inside the sandbox (port 3128)
    +        // which forwards to the Unix socket that bridges to the host's proxy server
    +        const proxyEnv = generateProxyEnvVars(
    +          3128, // Internal HTTP listener port
    +          1080, // Internal SOCKS listener port
             )
    -      }
    -      if (socksProxyPort !== undefined) {
             bwrapArgs.push(
    -          '--setenv',
    -          'CLAUDE_CODE_HOST_SOCKS_PROXY_PORT',
    -          String(socksProxyPort),
    +          ...proxyEnv.flatMap((env: string) => {
    +            const firstEq = env.indexOf('=')
    +            const key = env.slice(0, firstEq)
    +            const value = env.slice(firstEq + 1)
    +            return ['--setenv', key, value]
    +          }),
             )
    +
    +        // Add host proxy port environment variables for debugging/transparency
    +        // These show which host ports the Unix socket bridges connect to
    +        if (httpProxyPort !== undefined) {
    +          bwrapArgs.push(
    +            '--setenv',
    +            'CLAUDE_CODE_HOST_HTTP_PROXY_PORT',
    +            String(httpProxyPort),
    +          )
    +        }
    +        if (socksProxyPort !== undefined) {
    +          bwrapArgs.push(
    +            '--setenv',
    +            'CLAUDE_CODE_HOST_SOCKS_PROXY_PORT',
    +            String(socksProxyPort),
    +          )
    +        }
           }
    +      // If no sockets provided, network is completely blocked (--unshare-net without proxy)
         }
     
         // ========== FILESYSTEM RESTRICTIONS ==========
    
  • src/sandbox/sandbox-manager.ts+33 10 modified
    @@ -495,12 +495,27 @@ async function wrapWithSandbox(
           customConfig?.filesystem?.denyRead ?? config?.filesystem.denyRead ?? [],
       }
     
    -  // Check if network proxy is needed based on allowed domains
    -  // Unix sockets are local IPC and don't require the network proxy
    +  // Check if network config is specified - this determines if we need network restrictions
    +  // Network restriction is needed when:
    +  // 1. customConfig has network.allowedDomains defined (even if empty array = block all)
    +  // 2. OR config has network.allowedDomains defined (even if empty array = block all)
    +  // An empty allowedDomains array means "no domains allowed" = block all network access
    +  const hasNetworkConfig =
    +    customConfig?.network?.allowedDomains !== undefined ||
    +    config?.network?.allowedDomains !== undefined
    +
    +  // Get the actual allowed domains list for proxy filtering
       const allowedDomains =
         customConfig?.network?.allowedDomains ??
         config?.network.allowedDomains ??
         []
    +
    +  // Network RESTRICTION is needed whenever network config is specified
    +  // This includes empty allowedDomains which means "block all network"
    +  const needsNetworkRestriction = hasNetworkConfig
    +
    +  // Network PROXY is only needed when there are domains to filter
    +  // If allowedDomains is empty, we block all network and don't need the proxy
       const needsNetworkProxy = allowedDomains.length > 0
     
       // Wait for network initialization only if proxy is actually needed
    @@ -512,9 +527,10 @@ async function wrapWithSandbox(
         case 'macos':
           return await wrapCommandWithSandboxMacOS({
             command,
    -        needsNetworkRestriction: needsNetworkProxy,
    -        httpProxyPort: getProxyPort(),
    -        socksProxyPort: getSocksProxyPort(),
    +        needsNetworkRestriction,
    +        // Only pass proxy ports if proxy is running (when there are domains to filter)
    +        httpProxyPort: needsNetworkProxy ? getProxyPort() : undefined,
    +        socksProxyPort: needsNetworkProxy ? getSocksProxyPort() : undefined,
             readConfig,
             writeConfig,
             allowUnixSockets: getAllowUnixSockets(),
    @@ -528,11 +544,18 @@ async function wrapWithSandbox(
         case 'linux':
           return wrapCommandWithSandboxLinux({
             command,
    -        needsNetworkRestriction: needsNetworkProxy,
    -        httpSocketPath: getLinuxHttpSocketPath(),
    -        socksSocketPath: getLinuxSocksSocketPath(),
    -        httpProxyPort: managerContext?.httpProxyPort,
    -        socksProxyPort: managerContext?.socksProxyPort,
    +        needsNetworkRestriction,
    +        // Only pass socket paths if proxy is running (when there are domains to filter)
    +        httpSocketPath: needsNetworkProxy ? getLinuxHttpSocketPath() : undefined,
    +        socksSocketPath: needsNetworkProxy
    +          ? getLinuxSocksSocketPath()
    +          : undefined,
    +        httpProxyPort: needsNetworkProxy
    +          ? managerContext?.httpProxyPort
    +          : undefined,
    +        socksProxyPort: needsNetworkProxy
    +          ? managerContext?.socksProxyPort
    +          : undefined,
             readConfig,
             writeConfig,
             enableWeakerNestedSandbox: getEnableWeakerNestedSandbox(),
    
  • test/sandbox/integration.test.ts+320 0 modified
    @@ -947,3 +947,323 @@ describe('Sandbox Integration Tests', () => {
         })
       })
     })
    +
    +/**
    + * Integration tests for the empty allowedDomains vulnerability fix
    + *
    + * These tests verify the ACTUAL network behavior when allowedDomains: [] is specified.
    + * With the fix:
    + * - Empty allowedDomains = ALL network access blocked (as documented)
    + * - Non-empty allowedDomains = Only specified domains allowed
    + *
    + * The bug caused empty allowedDomains to allow ALL network access instead.
    + */
    +describe('Empty allowedDomains Network Blocking Integration', () => {
    +  const TEST_DIR = join(process.cwd(), '.sandbox-test-empty-domains')
    +
    +  beforeAll(async () => {
    +    if (skipIfNotLinux()) {
    +      return
    +    }
    +
    +    // Create test directory
    +    if (!existsSync(TEST_DIR)) {
    +      mkdirSync(TEST_DIR, { recursive: true })
    +    }
    +  })
    +
    +  afterAll(async () => {
    +    if (skipIfNotLinux()) {
    +      return
    +    }
    +
    +    // Clean up test directory
    +    if (existsSync(TEST_DIR)) {
    +      rmSync(TEST_DIR, { recursive: true, force: true })
    +    }
    +
    +    await SandboxManager.reset()
    +  })
    +
    +  describe('Network blocked with empty allowedDomains', () => {
    +    beforeAll(async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      // Initialize with empty allowedDomains - should block ALL network
    +      await SandboxManager.reset()
    +      await SandboxManager.initialize({
    +        network: {
    +          allowedDomains: [], // Empty = block all network (documented behavior)
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: [TEST_DIR],
    +          denyWrite: [],
    +        },
    +      })
    +    })
    +
    +    it('should block all HTTP requests when allowedDomains is empty', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      // Try to access example.com - should be blocked
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'curl -s --max-time 2 --connect-timeout 2 http://example.com 2>&1 || echo "network_failed"',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 5000,
    +      })
    +
    +      // With empty allowedDomains, network should be completely blocked
    +      // curl should fail with network-related error
    +      const output = (result.stdout + result.stderr).toLowerCase()
    +
    +      // Network should fail - either connection error, timeout, or "network_failed" echo
    +      const networkBlocked =
    +        output.includes('network_failed') ||
    +        output.includes('couldn\'t connect') ||
    +        output.includes('connection refused') ||
    +        output.includes('network is unreachable') ||
    +        output.includes('name or service not known') ||
    +        output.includes('timed out') ||
    +        output.includes('connection timed out') ||
    +        result.status !== 0
    +
    +      expect(networkBlocked).toBe(true)
    +
    +      // Should NOT contain successful HTML response
    +      expect(output).not.toContain('example domain')
    +      expect(output).not.toContain('<!doctype')
    +    })
    +
    +    it('should block all HTTPS requests when allowedDomains is empty', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'curl -s --max-time 2 --connect-timeout 2 https://example.com 2>&1 || echo "network_failed"',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 5000,
    +      })
    +
    +      const output = (result.stdout + result.stderr).toLowerCase()
    +
    +      // Network should fail
    +      const networkBlocked =
    +        output.includes('network_failed') ||
    +        output.includes('couldn\'t connect') ||
    +        output.includes('connection refused') ||
    +        output.includes('network is unreachable') ||
    +        output.includes('name or service not known') ||
    +        output.includes('timed out') ||
    +        result.status !== 0
    +
    +      expect(networkBlocked).toBe(true)
    +    })
    +
    +    it('should block DNS lookups when allowedDomains is empty', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      // Try DNS lookup - should fail with no network
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'host example.com 2>&1 || nslookup example.com 2>&1 || echo "dns_failed"',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 5000,
    +      })
    +
    +      const output = (result.stdout + result.stderr).toLowerCase()
    +
    +      // DNS should fail when network is blocked
    +      const dnsBlocked =
    +        output.includes('dns_failed') ||
    +        output.includes('connection timed out') ||
    +        output.includes('no servers could be reached') ||
    +        output.includes('network is unreachable') ||
    +        output.includes('name or service not known') ||
    +        output.includes('temporary failure') ||
    +        result.status !== 0
    +
    +      expect(dnsBlocked).toBe(true)
    +    })
    +
    +    it('should block wget when allowedDomains is empty', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'wget -q --timeout=2 -O - http://example.com 2>&1 || echo "wget_failed"',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 5000,
    +      })
    +
    +      const output = (result.stdout + result.stderr).toLowerCase()
    +
    +      // wget should fail
    +      const wgetBlocked =
    +        output.includes('wget_failed') ||
    +        output.includes('failed') ||
    +        output.includes('network is unreachable') ||
    +        output.includes('unable to resolve') ||
    +        result.status !== 0
    +
    +      expect(wgetBlocked).toBe(true)
    +    })
    +
    +    it('should allow local filesystem operations when network is blocked', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      // Even with network blocked, filesystem should work
    +      const testFile = join(TEST_DIR, 'network-blocked-test.txt')
    +      const testContent = 'test content with network blocked'
    +
    +      const command = await SandboxManager.wrapWithSandbox(
    +        `echo "${testContent}" > ${testFile} && cat ${testFile}`,
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        cwd: TEST_DIR,
    +        timeout: 5000,
    +      })
    +
    +      expect(result.status).toBe(0)
    +      expect(result.stdout).toContain(testContent)
    +
    +      // Cleanup
    +      if (existsSync(testFile)) {
    +        unlinkSync(testFile)
    +      }
    +    })
    +  })
    +
    +  describe('Network allowed with specific domains', () => {
    +    beforeAll(async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      // Reinitialize with specific domain allowed
    +      await SandboxManager.reset()
    +      await SandboxManager.initialize({
    +        network: {
    +          allowedDomains: ['example.com'], // Only example.com allowed
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: [TEST_DIR],
    +          denyWrite: [],
    +        },
    +      })
    +    })
    +
    +    it('should allow HTTP to explicitly allowed domain', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'curl -s --max-time 5 http://example.com 2>&1',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 10000,
    +      })
    +
    +      // Should succeed and return HTML
    +      expect(result.status).toBe(0)
    +      expect(result.stdout).toContain('Example Domain')
    +    })
    +
    +    it('should block HTTP to non-allowed domain', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'curl -s --max-time 2 http://anthropic.com 2>&1',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 5000,
    +      })
    +
    +      const output = result.stdout.toLowerCase()
    +      // Should be blocked by proxy
    +      expect(output).toContain('blocked by network allowlist')
    +    })
    +  })
    +
    +  describe('Contrast: empty vs undefined network config', () => {
    +    it('empty allowedDomains should block network', async () => {
    +      if (skipIfNotLinux()) {
    +        return
    +      }
    +
    +      await SandboxManager.reset()
    +      await SandboxManager.initialize({
    +        network: {
    +          allowedDomains: [], // Explicitly empty
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: [TEST_DIR],
    +          denyWrite: [],
    +        },
    +      })
    +
    +      const command = await SandboxManager.wrapWithSandbox(
    +        'curl -s --max-time 2 http://example.com 2>&1 || echo "blocked"',
    +      )
    +
    +      const result = spawnSync(command, {
    +        shell: true,
    +        encoding: 'utf8',
    +        timeout: 5000,
    +      })
    +
    +      // Should be blocked
    +      const output = (result.stdout + result.stderr).toLowerCase()
    +      const isBlocked =
    +        output.includes('blocked') ||
    +        output.includes('couldn\'t connect') ||
    +        output.includes('network is unreachable') ||
    +        result.status !== 0
    +
    +      expect(isBlocked).toBe(true)
    +      expect(output).not.toContain('example domain')
    +    })
    +  })
    +})
    
  • test/sandbox/wrap-with-sandbox.test.ts+241 0 modified
    @@ -408,5 +408,246 @@ describe('restriction pattern semantics', () => {
           expect(result).not.toBe(command)
           expect(result).toContain('sandbox-exec')
         })
    +
    +    // Tests for the empty allowedDomains fix (CVE fix)
    +    // Empty allowedDomains should block all network, not allow all
    +    it('needsNetworkRestriction true without proxy sockets blocks all network on Linux', async () => {
    +      if (getPlatform() !== 'linux') {
    +        return
    +      }
    +
    +      // Network restriction enabled but no proxy sockets = block all network
    +      const result = await wrapCommandWithSandboxLinux({
    +        command,
    +        needsNetworkRestriction: true,
    +        httpSocketPath: undefined, // No proxy available
    +        socksSocketPath: undefined, // No proxy available
    +        readConfig: { denyOnly: [] },
    +        writeConfig: { allowOnly: ['/tmp'], denyWithinAllow: [] },
    +      })
    +
    +      // Should wrap with --unshare-net to block all network
    +      expect(result).not.toBe(command)
    +      expect(result).toContain('bwrap')
    +      expect(result).toContain('--unshare-net')
    +      // Should NOT contain proxy-related environment variables since no proxy
    +      expect(result).not.toContain('HTTP_PROXY')
    +    })
    +
    +    it('needsNetworkRestriction true without proxy ports blocks all network on macOS', async () => {
    +      if (getPlatform() !== 'macos') {
    +        return
    +      }
    +
    +      // Network restriction enabled but no proxy ports = block all network
    +      const result = await wrapCommandWithSandboxMacOS({
    +        command,
    +        needsNetworkRestriction: true,
    +        httpProxyPort: undefined, // No proxy available
    +        socksProxyPort: undefined, // No proxy available
    +        readConfig: { denyOnly: [] },
    +        writeConfig: { allowOnly: ['/tmp'], denyWithinAllow: [] },
    +      })
    +
    +      // Should wrap with sandbox-exec
    +      expect(result).not.toBe(command)
    +      expect(result).toContain('sandbox-exec')
    +      // The sandbox profile should NOT contain "(allow network*)" since restrictions are enabled
    +      // Note: We can't easily check the profile content, but we verify it doesn't skip sandboxing
    +    })
    +
    +    it('needsNetworkRestriction true with proxy allows filtered network on Linux', async () => {
    +      if (getPlatform() !== 'linux') {
    +        return
    +      }
    +
    +      // Create temporary socket files for the test
    +      const fs = await import('fs')
    +      const os = await import('os')
    +      const path = await import('path')
    +      const tmpDir = os.tmpdir()
    +      const httpSocket = path.join(tmpDir, `test-http-${Date.now()}.sock`)
    +      const socksSocket = path.join(tmpDir, `test-socks-${Date.now()}.sock`)
    +
    +      // Create dummy socket files
    +      fs.writeFileSync(httpSocket, '')
    +      fs.writeFileSync(socksSocket, '')
    +
    +      try {
    +        const result = await wrapCommandWithSandboxLinux({
    +          command,
    +          needsNetworkRestriction: true,
    +          httpSocketPath: httpSocket,
    +          socksSocketPath: socksSocket,
    +          httpProxyPort: 3128,
    +          socksProxyPort: 1080,
    +          readConfig: { denyOnly: [] },
    +          writeConfig: { allowOnly: ['/tmp'], denyWithinAllow: [] },
    +        })
    +
    +        // Should wrap with network namespace isolation
    +        expect(result).not.toBe(command)
    +        expect(result).toContain('bwrap')
    +        expect(result).toContain('--unshare-net')
    +        // Should bind the socket files
    +        expect(result).toContain(httpSocket)
    +        expect(result).toContain(socksSocket)
    +      } finally {
    +        // Cleanup
    +        fs.unlinkSync(httpSocket)
    +        fs.unlinkSync(socksSocket)
    +      }
    +    })
    +
    +    it('needsNetworkRestriction true with proxy allows filtered network on macOS', async () => {
    +      if (getPlatform() !== 'macos') {
    +        return
    +      }
    +
    +      const result = await wrapCommandWithSandboxMacOS({
    +        command,
    +        needsNetworkRestriction: true,
    +        httpProxyPort: 3128,
    +        socksProxyPort: 1080,
    +        readConfig: { denyOnly: [] },
    +        writeConfig: { allowOnly: ['/tmp'], denyWithinAllow: [] },
    +      })
    +
    +      // Should wrap with sandbox-exec and proxy env vars
    +      expect(result).not.toBe(command)
    +      expect(result).toContain('sandbox-exec')
    +      // Should set proxy environment variables
    +      expect(result).toContain('HTTP_PROXY')
    +      expect(result).toContain('HTTPS_PROXY')
    +    })
    +  })
    +})
    +
    +/**
    + * Tests for the empty allowedDomains vulnerability fix
    + *
    + * These tests verify that when allowedDomains is explicitly set to an empty array [],
    + * network access is blocked (as documented) rather than allowed (the bug).
    + *
    + * Documentation states: "Empty array = no network access"
    + * Bug behavior: Empty array = full unrestricted network access
    + * Fixed behavior: Empty array = network isolation enabled, all network blocked
    + */
    +describe('empty allowedDomains network blocking (CVE fix)', () => {
    +  const command = 'curl https://example.com'
    +
    +  describe('SandboxManager.wrapWithSandbox with empty allowedDomains', () => {
    +    beforeAll(async () => {
    +      if (skipIfUnsupportedPlatform()) {
    +        return
    +      }
    +      // Initialize with domains so proxy starts, then test with empty customConfig
    +      await SandboxManager.initialize({
    +        network: {
    +          allowedDomains: ['example.com'],
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: ['/tmp'],
    +          denyWrite: [],
    +        },
    +      })
    +    })
    +
    +    afterAll(async () => {
    +      if (skipIfUnsupportedPlatform()) {
    +        return
    +      }
    +      await SandboxManager.reset()
    +    })
    +
    +    it('empty allowedDomains in customConfig triggers network restriction on Linux', async () => {
    +      if (getPlatform() !== 'linux') {
    +        return
    +      }
    +
    +      const result = await SandboxManager.wrapWithSandbox(command, undefined, {
    +        network: {
    +          allowedDomains: [], // Empty = block all network (documented behavior)
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: ['/tmp'],
    +          denyWrite: [],
    +        },
    +      })
    +
    +      // With the fix, empty allowedDomains should trigger network isolation
    +      expect(result).not.toBe(command)
    +      expect(result).toContain('bwrap')
    +      expect(result).toContain('--unshare-net')
    +    })
    +
    +    it('empty allowedDomains in customConfig triggers network restriction on macOS', async () => {
    +      if (getPlatform() !== 'macos') {
    +        return
    +      }
    +
    +      const result = await SandboxManager.wrapWithSandbox(command, undefined, {
    +        network: {
    +          allowedDomains: [], // Empty = block all network (documented behavior)
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: ['/tmp'],
    +          denyWrite: [],
    +        },
    +      })
    +
    +      // With the fix, empty allowedDomains should trigger sandbox
    +      expect(result).not.toBe(command)
    +      expect(result).toContain('sandbox-exec')
    +    })
    +
    +    it('non-empty allowedDomains still works correctly', async () => {
    +      if (skipIfUnsupportedPlatform()) {
    +        return
    +      }
    +
    +      const result = await SandboxManager.wrapWithSandbox(command, undefined, {
    +        network: {
    +          allowedDomains: ['example.com'], // Specific domain allowed
    +          deniedDomains: [],
    +        },
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: ['/tmp'],
    +          denyWrite: [],
    +        },
    +      })
    +
    +      // Should still wrap with sandbox
    +      expect(result).not.toBe(command)
    +      // Should have proxy environment variables for filtering
    +      expect(result).toContain('HTTP_PROXY')
    +    })
    +
    +    it('undefined network config in customConfig falls back to main config', async () => {
    +      if (skipIfUnsupportedPlatform()) {
    +        return
    +      }
    +
    +      const result = await SandboxManager.wrapWithSandbox(command, undefined, {
    +        // No network config - should fall back to main config which has example.com
    +        filesystem: {
    +          denyRead: [],
    +          allowWrite: ['/tmp'],
    +          denyWrite: [],
    +        },
    +      })
    +
    +      // Should wrap with sandbox using main config's network settings
    +      expect(result).not.toBe(command)
    +      // Main config has example.com, so proxy should be set up
    +      expect(result).toContain('HTTP_PROXY')
    +    })
       })
     })
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.