Domain & Network Integration Test Analysis

February 25, 2026 · View on GitHub

Generated 2026-02-25. Covers 6 test files in tests/integration/ related to domain filtering, wildcard patterns, network security, DNS, and localhost access.


Table of Contents

  1. blocked-domains.test.ts
  2. wildcard-patterns.test.ts
  3. empty-domains.test.ts
  4. network-security.test.ts
  5. dns-servers.test.ts
  6. localhost-access.test.ts
  7. Cross-Cutting Gaps

1. blocked-domains.test.ts

File: tests/integration/blocked-domains.test.ts (185 lines, 9 tests)

What It Tests

#TestDescription
1should block specific domain even when parent is allowedAllows github.com, accesses api.github.com — verifies subdomain auto-inclusion (expects success, not actually testing block)
2should allow requests to allowed domainsSimple allow-list test: github.com allows api.github.com/zen
3should block requests to non-allowed domainsWith only github.com allowed, example.com is blocked (expects toFail)
4should handle multiple blocked domainsTwo domains in allow-list (github.com, npmjs.org), verifies api.github.com succeeds
5should show allowed domains in debug outputVerifies [INFO] Allowed domains: appears in stderr with --log-level debug
6should handle case-insensitive domain matchingAccesses https://API.GITHUB.COM/zen with github.com in allow-list — DNS/Squid are case-insensitive
7should handle domains with trailing dotsAllows github.com. (FQDN trailing dot) — verifies normalization handles it
8should handle domains with leading/trailing whitespaceAllows github.com — verifies parseDomains() trims whitespace
9should block IP address access when only domain is allowedResolves api.github.com to IP, curls the raw IP — expects block

Real-World Mapping

TestReal-World Scenario
#1-2When Claude/Copilot agents access api.github.com with github.com whitelisted — the most common AWF configuration
#3When a malicious prompt causes an agent to access a non-whitelisted domain (e.g., exfiltrating code to attacker domain)
#4Multi-service workflow: agent needs GitHub API + npm registry
#6-8Robustness against variant domain representations in agent HTTP clients (Node.js fetch, Python requests, curl)
#9SSRF mitigation: agent resolves domain to IP and curls IP directly to bypass domain filtering

Gaps and Missing Coverage

  1. No actual --block-domains flag testing: Despite the file name, no test uses the --block-domains CLI option. All tests use --allow-domains only. The blockedDomains field in AwfRunner options isn't even defined.
  2. No block-overrides-allow precedence test: The Squid config places blocked domain ACLs before allowed domain ACLs. No test verifies that --block-domains internal.corp.com --allow-domains corp.com actually blocks internal.corp.com.
  3. No --block-domains-file test: File-based blocklist parsing is untested in integration.
  4. No --allow-domains-file test: File-based allowlist parsing is untested in integration (only unit-tested in cli.test.ts).
  5. Test #1 is misleading: Named "should block specific domain even when parent is allowed" but doesn't actually test blocking — it just tests subdomain inclusion. The test name suggests --block-domains functionality.
  6. No test for blocking a subdomain while allowing parent: e.g., --allow-domains github.com --block-domains api.github.com then verify api.github.com is blocked but github.com works.

Edge Cases Missing

  • Domain with port number (e.g., example.com:8080)
  • Punycode / internationalized domain names (e.g., xn--nxasmq6b.example.com)
  • Domain that is a prefix of an allowed domain (e.g., allow github.com, test github.com.evil.com — should be blocked)
  • Multiple consecutive requests to different domains in the same container session
  • Very long domain names (close to 253 char RFC limit)

2. wildcard-patterns.test.ts

File: tests/integration/wildcard-patterns.test.ts (185 lines, 11 tests)

What It Tests

#TestDescribe BlockDescription
1should allow subdomain with *.github.com patternLeading Wildcard*.github.com allows api.github.com
2should allow raw.githubusercontent.comLeading Wildcard*.githubusercontent.com + github.com allows raw.githubusercontent.com
3should allow nested subdomainsLeading Wildcard*.github.com allows api.github.com (duplicate of #1)
4should match domain case-insensitivelyCase Insensitivitygithub.com allows API.GITHUB.COM
5should match wildcard pattern case-insensitivelyCase Insensitivity*.GitHub.COM allows API.GITHUB.COM
6should allow exact domain matchPlain Domaingithub.com allows github.com/robots.txt
7should allow subdomains of plain domainPlain Domaingithub.com implicitly allows api.github.com
8should allow domains matching any of multiple patternsMultiple PatternsThree wildcard patterns, one domain tested
9should combine wildcard and plain domain patternsMultiple PatternsMixed wildcard + plain domain list
10should block domain not matching any patternNon-Matching*.github.com blocks example.com
11should block similar-looking domainNon-Matching*.github.com blocks notgithub.com (suffix attack)

Real-World Mapping

TestReal-World Scenario
#1-3Agent accessing GitHub API, raw file downloads — extremely common in agentic workflows
#2When Claude downloads raw files from GitHub repos for code review
#4-5HTTP client libraries may normalize case differently — ensures consistent behavior
#6-7Core domain filtering: github.com in frontmatter allows all GitHub subdomains
#8-9Complex workflows needing multiple code hosting platforms (GitHub + GitLab + Bitbucket)
#10-11Security: preventing domain confusion attacks where notgithub.com could be attacker-controlled

Gaps and Missing Coverage

  1. No mid-domain wildcard test: api-*.example.com pattern is mentioned in domain-patterns.ts docs but never tested in integration. This pattern is supported by the wildcardToRegex() function.
  2. No deeply nested subdomain test: e.g., *.github.com should match a.b.c.github.com. The regex [a-zA-Z0-9.-]* allows dots, so this should work, but it's untested.
  3. No bare wildcard exclusion test: *.github.com should NOT match github.com itself (only subdomains). This is a critical semantic difference that's untested.
  4. Test #3 is a duplicate of #1: Both test *.github.com allowing api.github.com.
  5. No protocol-specific wildcard test: e.g., https://*.github.com — the domain-patterns module supports this but it's not integration-tested.
  6. No test for multiple wildcards matching the same domain: e.g., both *.github.com and *.com — verifies no regex conflict.

Edge Cases Missing

  • Wildcard with only TLD: *.com (should this be rejected as too broad? Currently validateDomainOrPattern doesn't explicitly reject it)
  • Trailing dot with wildcard: *.github.com.
  • Empty subdomain match: does *.github.com match .github.com?
  • Wildcard pattern that overlaps with a plain domain in the allow-list

3. empty-domains.test.ts

File: tests/integration/empty-domains.test.ts (149 lines, 8 tests)

What It Tests

#TestDescribe BlockDescription
1should block all network access when no domains are specifiedNetwork BlockingallowDomains: [] blocks https://example.com
2should block HTTPS trafficNetwork BlockingEmpty allow-list blocks https://api.github.com
3should block HTTP trafficNetwork BlockingEmpty allow-list blocks http://httpbin.org
4should allow commands that do not require networkOffline Commandsecho "Hello" works with empty allow-list
5should allow file system operationsOffline CommandsFile create/read/delete works without network
6should allow local computationsOffline Commandsexpr 2 + 2 works without network
7should indicate no domains in debug outputDebug OutputStderr matches No allowed domains specified or all network access will be blocked
8should block network even when DNS resolution succeedsDNS BehaviorDNS resolves but HTTP connection still blocked

Real-World Mapping

TestReal-World Scenario
#1-3"Air-gapped" agent mode: running code analysis or refactoring that needs zero network access. This is the safest mode for untrusted code.
#4-6Agent performs local-only tasks (file editing, computation) inside the sandbox — must work even with all network blocked
#7Operator debugging: seeing confirmation that no domains are configured
#8Defense-in-depth: even if DNS leaks (which it does — DNS is allowed through), the HTTP/HTTPS layer still blocks connections

Gaps and Missing Coverage

  1. No test for DNS exfiltration: DNS queries are allowed even with empty domains. An attacker could encode data in DNS queries to exfiltrate secrets. There's no test for DNS-based data exfiltration (though --dns-servers limits which DNS servers are reachable).
  2. No test for non-HTTP protocols: What about SSH (port 22), SMTP (port 25), or raw TCP? These should be blocked by iptables rules, but aren't tested in this file.
  3. No test for localhost access with empty domains: Can the agent connect to 127.0.0.1 services with empty domains?
  4. No test for the --allow-domains flag being completely omitted (vs. passed as empty): The CLI behavior may differ.

Edge Cases Missing

  • UDP traffic (e.g., DNS-over-UDP to a custom server on a non-standard port)
  • ICMP/ping with empty domains
  • Agent trying to curl localhost or 127.0.0.1 with empty domains

4. network-security.test.ts

File: tests/integration/network-security.test.ts (232 lines, 14 tests)

What It Tests

#TestDescribe BlockDescription
1should drop NET_ADMIN after iptables setupCapability Restrictionsiptables -t nat -L OUTPUT fails inside container
2should block iptables flush attemptCapability Restrictionsiptables -t nat -F OUTPUT fails (can't flush NAT rules)
3should block iptables delete attemptCapability Restrictionsiptables -t nat -D OUTPUT 1 fails (can't delete rules)
4should block iptables insert attemptCapability Restrictionsiptables -t nat -I OUTPUT -j ACCEPT fails (can't add ACCEPT rule)
5should block curl --connect-to bypassFirewall Bypasscurl --connect-to ::github.com: https://example.com — tries to resolve example.com via github.com IP
6should block NO_PROXY bypassFirewall BypassNO_PROXY='*' doesn't bypass the firewall (because firewall uses iptables, not env vars)
7should block ALL_PROXY bypassFirewall BypassALL_PROXY='' doesn't bypass the firewall
8should block AWS metadata endpointSSRF Protection169.254.169.254 is blocked
9should block AWS metadata with pathSSRF Protection169.254.169.254/latest/meta-data/ is blocked
10should block GCP metadata endpointSSRF Protectionmetadata.google.internal with GCP header is blocked
11should block Azure metadata endpointSSRF Protection169.254.169.254/metadata/instance with Azure header is blocked
12should block DNS over HTTPS (DoH)DNS Securitycloudflare-dns.com/dns-query is blocked
13should block Google DoH endpointDNS Securitydns.google/dns-query is blocked
14should maintain firewall after bypass attemptEffectivenessAttempts iptables flush then curl example.com — both fail

Real-World Mapping

TestReal-World Scenario
#1-4Critical security: Malicious prompt injection causes agent to try modifying iptables rules to disable the firewall. The capsh --drop=cap_net_admin in entrypoint.sh prevents this.
#5Sophisticated bypass: agent uses curl --connect-to to route blocked domain through allowed domain's IP
#6-7Agent sets proxy-bypass env vars hoping to avoid Squid. AWF uses iptables DNAT (L3), not proxy env vars, so this doesn't work.
#8-11SSRF protection: Agent on cloud infrastructure (AWS/GCP/Azure) tries to access instance metadata to steal credentials. This is a top OWASP risk.
#12-13Agent tries DNS-over-HTTPS to exfiltrate data or resolve blocked domains via an encrypted channel
#14Compound attack: first try to disable firewall, then access blocked domain

Gaps and Missing Coverage

  1. No test for http_proxy/https_proxy override: Agent could set http_proxy=direct:// or https_proxy= to try bypassing. While AWF uses iptables DNAT, this should still be tested.
  2. No test for iptables -A (append) bypass: Tests cover -F (flush), -D (delete), -I (insert), but not -A (append).
  3. No test for ip route manipulation: Agent might try to add a route to bypass Squid. Should be blocked by dropped NET_ADMIN.
  4. No test for nsenter or container escape: Agent in container tries to escape to host namespace.
  5. No test for SSRF via DNS rebinding: Agent resolves allowed domain that DNS-rebinds to internal IP (e.g., 169.254.169.254).
  6. No test for SSRF via redirect: Agent accesses allowed domain that returns HTTP 302 redirect to http://169.254.169.254.
  7. No 169.254.0.0/16 link-local range test: Only 169.254.169.254 (metadata) is tested — but other link-local IPs could be dangerous.
  8. No test for IMDSv2 (token-based): AWS IMDSv2 uses PUT to get a token first, then GET metadata. Only IMDSv1-style requests are tested.
  9. No test for internal Docker network access: Can agent reach 172.30.0.10 (Squid) or 172.30.0.1 (gateway) directly?

Edge Cases Missing

  • curl --resolve bypass (similar to --connect-to)
  • Agent using socat or nc for raw TCP connections
  • Agent trying to use container's Docker socket if mounted
  • Agent trying to use IPv6 link-local addresses
  • Agent modifying /etc/resolv.conf to point to a malicious DNS server

5. dns-servers.test.ts

File: tests/integration/dns-servers.test.ts (115 lines, 6 tests)

What It Tests

#TestDescription
1should resolve DNS with default serversnslookup github.com works with default DNS (8.8.8.8, 8.8.4.4)
2should resolve DNS with custom Google DNSnslookup github.com 8.8.8.8 works explicitly
3should resolve DNS with Cloudflare DNSnslookup github.com 1.1.1.1 works
4should show DNS servers in debug outputstderr contains DNS or dns
5should resolve multiple domains sequentiallynslookup github.com && nslookup api.github.com both succeed
6should resolve DNS for allowed domainsdig github.com +short returns IP addresses

Real-World Mapping

TestReal-World Scenario
#1Default configuration: agent resolves GitHub API before making requests
#2-3Organization mandates specific DNS servers (corporate DNS policy, Cloudflare for privacy)
#5Agent resolves multiple APIs during a workflow (GitHub + npm + PyPI)
#6Verifying DNS resolution actually returns IPs (not NXDOMAIN or empty)

Gaps and Missing Coverage

  1. No --dns-servers CLI option test: None of these tests actually use the --dns-servers flag. They all use default DNS. The dnsServers option exists in AwfRunner but is never passed.
  2. No DNS restriction test: With --dns-servers 8.8.8.8, can the agent still query 1.1.1.1? The iptables rules should block non-whitelisted DNS servers, but this is untested.
  3. No IPv6 DNS server test: isValidIPv6() exists in the CLI, but no integration test uses IPv6 DNS.
  4. No invalid DNS server test: What happens with --dns-servers 999.999.999.999? The CLI validates, but no integration test covers this path.
  5. No DNS resolution of blocked domains test: Can the agent resolve a domain that's NOT in the allow-list? (DNS resolution should succeed per design, but HTTP access should be blocked.)
  6. No DNS timeout/failure test: What happens when DNS servers are unreachable?

Edge Cases Missing

  • DNS resolution for non-existent domains (NXDOMAIN)
  • DNS resolution for domains with CNAME chains
  • DNS resolution with --dns-servers 127.0.0.1 (using container-local DNS)
  • Agent trying to use dig @attacker-dns.com with a non-whitelisted DNS server

6. localhost-access.test.ts

File: tests/integration/localhost-access.test.ts (138 lines, 8 tests)

What It Tests

#TestDescription
1should automatically enable host access when localhost is in allowed domainsallowDomains: ['localhost'] triggers security warning, auto-enables host access, auto-allows common dev ports
2should map localhost to host.docker.internallocalhost in allow-list becomes host.docker.internal in config
3should preserve http:// protocol prefixhttp://localhost becomes http://host.docker.internal
4should preserve https:// protocol prefixhttps://localhost becomes https://host.docker.internal
5should work with localhost combined with other domains['localhost', 'github.com', 'example.com'] — all domains present, localhost mapped
6should allow custom port range to override defaultallowHostPorts: '8080' overrides default port list (no "allowing common development ports" message)
7should resolve host.docker.internal from inside containergetent hosts host.docker.internal returns an IP
8should work for Playwright-style testing scenarioSimulates Playwright test context (just echo commands, no actual server)

Real-World Mapping

TestReal-World Scenario
#1-2Playwright testing: Agent runs Playwright tests against a local dev server (e.g., localhost:3000). AWF maps localhost to host.docker.internal so container can reach host services.
#3-4Protocol-specific access: agent needs HTTP-only or HTTPS-only to localhost
#5Agent needs both localhost (for dev server) and external domains (for API calls)
#6Custom dev server on non-standard port (e.g., 8080 for Spring Boot)
#7Container DNS resolution: host.docker.internal must resolve to the Docker host IP
#8End-to-end Playwright-style usage (though mocked — no actual HTTP server)

Gaps and Missing Coverage

  1. No actual HTTP request to localhost: No test starts a server on the host and verifies the agent can reach it. Test #8 is just echo commands.
  2. No test for port filtering: Do the auto-allowed ports (3000, 4200, 5173, 8080, etc.) actually work? Is port 22 (SSH) blocked?
  3. No test for dangerous port blocking: squid-config.ts defines DANGEROUS_PORTS (22, 3306, 5432, 6379, etc.) that should be blocked even with --allow-host-ports. No integration test verifies this.
  4. No test for --enable-host-access without localhost keyword: The flag can be set directly without using the localhost keyword.
  5. No test for multiple localhost entries: e.g., ['localhost', 'http://localhost'] — how is this handled?
  6. No test for localhost:PORT format: Users might try localhost:3000 as a domain.

Edge Cases Missing

  • Agent trying to access host Docker socket via host.docker.internal
  • Agent accessing host-bound services on non-standard interfaces (e.g., 0.0.0.0 vs 127.0.0.1)
  • Port range specification (e.g., 3000-4000)
  • Localhost with IPv6 (::1)

7. Cross-Cutting Gaps

Infrastructure Issues

  1. No --block-domains support in AwfRunner: The test runner (awf-runner.ts) doesn't have a blockDomains option, making it impossible to test the blocklist feature in integration tests without modifying the runner.

  2. No protocol-specific integration tests: The domain-patterns.ts module supports http://, https:// prefixes on domains, and squid-config.ts generates protocol-specific ACLs (allowed_http_only, allowed_https_only). None of this is integration-tested.

  3. No SSL Bump integration tests: The --ssl-bump feature generates entirely different Squid config (with CA certs, ssl_bump peek/stare/bump). No integration test covers this.

  4. No --allow-urls integration tests: URL-level filtering (requires --ssl-bump) is untested in integration.

Security Scenarios Not Covered

ScenarioRiskCurrent Coverage
DNS rebinding attackAgent resolves allowed domain -> attacker DNS returns internal IPNone
HTTP redirect to internalAllowed domain returns 302 to 169.254.169.254None
Domain frontingAgent uses TLS SNI of allowed domain but HTTP Host header of blocked domainNone
Slowloris / connection exhaustionAgent opens many connections to exhaust Squid resourcesNone
Data exfiltration via DNSEncode secrets in DNS query labelsNone
Agent modifying proxy configAgent writes to /etc/environment or /etc/profile.d/None
Time-of-check/time-of-useDomain resolves to allowed IP during check, then changesNone
  1. block-domains.test.ts — Dedicated tests for --block-domains and --block-domains-file functionality
  2. protocol-filtering.test.ts — Tests for http:// and https:// protocol-specific domain filtering
  3. host-access.test.ts — Tests for --enable-host-access with an actual HTTP server on the host, port filtering, dangerous port blocking
  4. ssl-bump.test.ts — Tests for SSL Bump mode with URL-level filtering
  5. dns-restriction.test.ts — Tests for --dns-servers actually restricting which DNS servers the agent can query