From dbf69fe645e17627d494328b2ec69422a306821f Mon Sep 17 00:00:00 2001 From: km-anthropic Date: Sun, 13 Jul 2025 08:36:02 -0700 Subject: [PATCH] test: add network restrictions verification test --- .github/workflows/claude.yml | 17 +++++----- test/network-restrictions.test.ts | 54 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 test/network-restrictions.test.ts diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 42daf066..685234c0 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -29,35 +29,34 @@ jobs: with: fetch-depth: 1 - - name: Setup Network Restrictions if: ${{ vars.DISABLE_NETWORK_RESTRICTIONS != 'true' }} run: | # Install and configure Squid proxy sudo apt-get update && sudo apt-get install -y squid - + # Create whitelist for allowed domains cat > /tmp/whitelist.txt << 'EOF' # Claude API .anthropic.com - + # GitHub (covers github.com, api.github.com, gist.github.com, etc.) .github.com - + # GitHub raw content and user uploads .githubusercontent.com - + # GitHub Container Registry ghcr.io - + # Package registries registry.npmjs.org bun.sh - + # Azure storage for GitHub Actions cache .blob.core.windows.net EOF - + # Configure Squid sudo tee /etc/squid/squid.conf << 'EOF' http_port 127.0.0.1:3128 @@ -67,7 +66,7 @@ jobs: http_access deny all cache deny all EOF - + # Stop any existing squid instance and start with our config sudo squid -k shutdown || true sleep 2 diff --git a/test/network-restrictions.test.ts b/test/network-restrictions.test.ts new file mode 100644 index 00000000..d0a4d998 --- /dev/null +++ b/test/network-restrictions.test.ts @@ -0,0 +1,54 @@ +import { describe, it, expect } from "bun:test"; + +describe("Network Restrictions", () => { + it("should block access to unauthorized domains", async () => { + // This test verifies that the proxy blocks unauthorized domains + const unauthorizedUrls = [ + "https://example.com/api/data", + "https://jsonplaceholder.typicode.com/posts", + "https://httpbin.org/get", + "https://pastebin.com/raw/example123", + "https://google.com", + ]; + + for (const url of unauthorizedUrls) { + try { + const response = await fetch(url, { + timeout: 5000, + // Force through proxy if set + agent: undefined, + }); + + // If we reach here, the proxy didn't block it - test should fail + expect(response.ok).toBe(false); + throw new Error(`Unauthorized domain ${url} was not blocked by proxy`); + } catch (error) { + // We expect an error (connection refused, timeout, etc) + // This is the desired behavior - proxy blocked the request + expect(error).toBeDefined(); + console.log(`✓ Successfully blocked: ${url}`); + } + } + }); + + it("should allow access to whitelisted domains", async () => { + // These should work through the proxy + const allowedUrls = [ + "https://api.github.com/zen", + "https://registry.npmjs.org/-/ping", + ]; + + for (const url of allowedUrls) { + try { + const response = await fetch(url, { timeout: 5000 }); + expect(response.ok).toBe(true); + console.log(`✓ Successfully allowed: ${url}`); + } catch (error) { + // If whitelisted domains fail, something is wrong + throw new Error( + `Whitelisted domain ${url} was blocked: ${error.message}`, + ); + } + } + }); +});