Skip to content

Conversation

@Mossaka
Copy link
Collaborator

@Mossaka Mossaka commented Feb 6, 2026

Summary

  • Restrict host gateway ACCEPT rule to ports 80, 443, and --allow-host-ports only (was: all ports)
  • Apply same port restriction to network gateway bypass
  • Add IPv4 format validation for dynamically resolved bypass IPs before iptables use
  • Mount chroot-hosts as read-only (:ro) since entry is pre-injected before mount

Security context

When --enable-host-access is set, setup-iptables.sh adds an iptables -A OUTPUT -d $HOST_GATEWAY_IP -j ACCEPT rule with no --dport restriction. This allows agent code to reach any service on the host machine — including databases (port 5432/3306/6379), admin panels, and other MCP servers — completely bypassing domain filtering and the dangerous-ports blocklist, with zero Squid logging.

Before (all ports open)

iptables -A OUTPUT -d 172.17.0.1 -j ACCEPT   # ALL ports!

After (restricted to allowed ports)

iptables -A OUTPUT -p tcp -d 172.17.0.1 --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp -d 172.17.0.1 --dport 443 -j ACCEPT
# + each port from --allow-host-ports

The NAT RETURN rule is unchanged — MCP traffic still bypasses Squid (which crashes on Streamable HTTP/SSE). Non-allowed port traffic now hits the final DROP rule in the FILTER chain.

Smoke test compatibility

  • smoke-chroot: uses --allow-domains localhost which auto-configures --allow-host-ports 3000,3001,...,9090 — all gateway ports are in the ACCEPT list
  • smoke-copilot/claude: MCP gateway runs on port 80 — always in the ACCEPT list
  • localhost keyword: auto-enables --allow-host-ports with common dev ports, so no change needed

Local verification

# Before fix: agent reaches host services on ALL ports
curl -sf http://host.docker.internal:7777 → SECRET_DATA_ON_PORT_7777 (EXIT=0)
curl -sf http://host.docker.internal:5432 → FAKE_POSTGRES_ON_PORT_5432 (EXIT=0)

# After fix: unauthorized ports blocked
curl -sf http://host.docker.internal:7777 → EXIT=28 (timeout/DROP)
curl -sf http://host.docker.internal:5432 → EXIT=28 (timeout/DROP)

# --allow-host-ports still works
awf --allow-host-ports 7777 ... → SECRET_DATA_ON_PORT_7777 (EXIT=0)

Test plan

  • npm test — 735/735 pass (updated test expects :ro mount)
  • npm run lint — pass
  • Local verification: unauthorized ports blocked, allowed ports work
  • CI: smoke-chroot, smoke-copilot, smoke-claude workflows

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings February 6, 2026 22:38
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 82.02% 82.18% 📈 +0.16%
Statements 82.06% 82.24% 📈 +0.18%
Functions 81.95% 81.95% ➡️ +0.00%
Branches 75.51% 75.67% 📈 +0.16%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/docker-manager.ts 82.6% → 83.3% (+0.69%) 81.9% → 82.7% (+0.76%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Node.js Build Test Results

Project Install Tests Status
clsx PASS PASS
execa PASS PASS
p-limit PASS PASS

Overall: PASS

All Node.js projects built and tested successfully.

AI generated by Build Test Node.js

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Smoke Test Results for Copilot

Status: PASS

cc @Mossaka

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Go Build Test Results

Project Download Tests Status
color 1/1 PASS
env 1/1 PASS
uuid 1/1 PASS

Overall: PASS

All Go projects successfully downloaded dependencies and passed tests.

AI generated by Build Test Go

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Deno Build Test Results

Project Tests Status
oak 1/1 ✅ PASS
std 1/1 ✅ PASS

Overall: ✅ PASS

All Deno tests completed successfully.

AI generated by Build Test Deno

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Build Test: Bun - FAILED ❌

Status: Test execution failed due to environment limitations

Test Results

Project Install Tests Status
elysia N/A FAILED
hono N/A FAILED

Overall: FAIL

Error Details

Root Cause: Bun requires a functional /proc filesystem which is not available in this execution environment.

Error: An internal error occurred (NotDir)

Environment Check:

  • Bun version: 1.3.8 ✅
  • Bun binary: Valid ELF executable ✅
  • /proc filesystem: Not mounted ❌

Impact: Unable to run bun install in any directory, preventing dependency installation and test execution for both elysia and hono projects.


This test cannot proceed without /proc access. Consider running in an environment with full /proc filesystem support.

AI generated by Build Test Bun

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Smoke Test: Claude Engine

Last 2 merged PRs:

Results:

  • ✅ GitHub MCP: Fetched PRs successfully
  • ❌ Playwright: Navigation timeout (60s)
  • ✅ File Write: Created /tmp/gh-aw/agent/smoke-test-claude-21768434701.txt
  • ✅ Bash: Verified file contents

Status: FAIL (Playwright timeout)

AI generated by Smoke Claude

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Chroot Version Comparison Test Results

Runtime Host Version Chroot Version Match?
Python 3.12.12 3.12.3 ❌ NO
Node.js v24.13.0 v20.20.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall Result: ❌ FAILED (not all runtimes matched)

The chroot environment successfully uses host-installed Go, but Python and Node.js versions differ between host and chroot environments.

AI generated by Smoke Chroot

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Tightens host-access networking controls by narrowing the iptables host/network gateway bypass to approved ports, adding basic IP validation before rule insertion, and hardening the chroot /etc/hosts mount mode.

Changes:

  • Restrict host/network gateway OUTPUT ACCEPT bypass to TCP ports 80/443 plus --allow-host-ports.
  • Add IPv4-format validation for dynamically resolved gateway IPs before using them in iptables.
  • Mount the generated chroot-hosts file as read-only and update the associated unit test.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/docker-manager.ts Changes chroot /etc/hosts mount to read-only when using generated chroot-hosts.
src/docker-manager.test.ts Updates test expectation to match the new :ro mount.
containers/agent/setup-iptables.sh Adds IPv4 validation and restricts gateway bypass ACCEPT rules to allowed ports only.
Comments suppressed due to low confidence (1)

containers/agent/setup-iptables.sh:151

  • AWF_ALLOW_HOST_PORTS supports range syntax like "3000-3010" (per CLI/docs), but these ACCEPT rules pass port_spec directly to iptables --dport. iptables’ TCP/UDP --dport range syntax is typically START:END, so a hyphenated range may error and abort setup-iptables.sh (set -e). Consider normalizing "START-END" to "START:END" (and handling single ports separately) before invoking iptables.
        port_spec=$(echo "$port_spec" | xargs)
        echo "[iptables]   Allow host gateway port $port_spec"
        iptables -A OUTPUT -p tcp -d "$HOST_GATEWAY_IP" --dport "$port_spec" -j ACCEPT
      done

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
fs.chmodSync(chrootHostsPath, 0o644);
agentVolumes.push(`${chrootHostsPath}:/host/etc/hosts`);
agentVolumes.push(`${chrootHostsPath}:/host/etc/hosts:ro`);
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mounting chroot-hosts as read-only can break host.docker.internal injection fallback: entrypoint.sh appends the container’s host.docker.internal line into /host/etc/hosts when AWF_ENABLE_HOST_ACCESS=1 and the entry is missing. With a :ro mount, that append will fail if docker-manager couldn’t resolve/append the gateway IP (the try/catch allows continuing), potentially leaving chroot without host.docker.internal resolution. Consider keeping this mount writable, or make docker-manager injection guaranteed and update entrypoint logic accordingly.

Suggested change
agentVolumes.push(`${chrootHostsPath}:/host/etc/hosts:ro`);
agentVolumes.push(`${chrootHostsPath}:/host/etc/hosts:rw`);

Copilot uses AI. Check for mistakes.
# Function to validate an IPv4 address format (e.g., 172.17.0.1)
is_valid_ipv4() {
local ip="$1"
echo "$ip" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_valid_ipv4 only checks a dotted-quad format, so values like 999.999.999.999 will pass and then cause iptables to error (and the script runs with set -e). It should validate each octet is 0–255 (and ideally reject 0.0.0.0/broadcast) to avoid failing open/DoS when name resolution returns unexpected output.

Suggested change
echo "$ip" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
# Split into octets
local IFS='.'
read -r -a octets <<< "$ip"
# Must have exactly 4 octets
if [ "${#octets[@]}" -ne 4 ]; then
return 1
fi
# Validate each octet is numeric and in range 0–255
local octet
for octet in "${octets[@]}"; do
# Numeric only
if ! [[ "$octet" =~ ^[0-9]+$ ]]; then
return 1
fi
# Range check; use 10#$octet to avoid octal interpretation
if (( 10#$octet < 0 || 10#$octet > 255 )); then
return 1
fi
done
# Reject unspecified and all-hosts broadcast addresses
if [[ "$ip" == "0.0.0.0" || "$ip" == "255.255.255.255" ]]; then
return 1
fi
return 0

Copilot uses AI. Check for mistakes.
Comment on lines +145 to +151
if [ -n "$AWF_ALLOW_HOST_PORTS" ]; then
IFS=',' read -ra HOST_PORTS <<< "$AWF_ALLOW_HOST_PORTS"
for port_spec in "${HOST_PORTS[@]}"; do
port_spec=$(echo "$port_spec" | xargs)
echo "[iptables] Allow host gateway port $port_spec"
iptables -A OUTPUT -p tcp -d "$HOST_GATEWAY_IP" --dport "$port_spec" -j ACCEPT
done
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gateway-bypass ACCEPT rules use AWF_ALLOW_HOST_PORTS values without validating range/format or excluding DANGEROUS_PORTS. Because AWF_ALLOW_HOST_PORTS can be user-controlled (e.g., via env override) this can re-open blocked ports on the host gateway/network gateway (e.g., 5432/6379) and bypass Squid + the dangerous-ports protection. Recommend validating/sanitizing port specs here (numeric/range within 1–65535) and explicitly rejecting any port(s) in the DANGEROUS_PORTS list before adding ACCEPT rules.

This issue also appears on line 148 of the same file.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Build Test: Java - Environment Issue ❌

Status: FAILED - Environment Configuration Error

Problem

The test could not run because Java/Maven are not functional in the current AWF chroot environment.

Technical Details

  • Repository clone: ✅ SUCCESS
  • Java/Maven execution: ❌ FAILED

Root Cause: The AWF chroot environment has /proc/self mounted but Java binaries cannot execute properly. All attempts to run Java result in bash version output instead of Java execution.

$ java -version
GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)
...

Environment detected:

  • AWF_CHROOT_ENABLED=true
  • /proc/self/exe/bin/bash (incorrect for Java execution)
  • Java binaries exist but cannot execute

Required Actions

One of the following solutions is needed:

  1. Fix chroot /proc configuration - Ensure Java can determine its own executable path
  2. Disable chroot mode for this workflow - Run without --enable-chroot flag
  3. Install Java in the chroot container - Make Java available within the container environment

Test Projects Status

Project Compile Tests Status
gson ❌ NOT RUN - BLOCKED
caffeine ❌ NOT RUN - BLOCKED

Overall: BLOCKED - Environment issue prevents testing

AI generated by Build Test Java

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Build Test: Rust - Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS

All Rust projects built and tested successfully.

AI generated by Build Test Rust

The --enable-host-access flag added an iptables ACCEPT rule for
host.docker.internal with no port restriction, allowing agent code
to reach ANY service on the host (databases, admin panels, etc.)
and bypassing the dangerous-ports blocklist entirely.

Changes:
- Restrict host gateway FILTER ACCEPT to ports 80, 443, and any
  ports from --allow-host-ports (was: all ports)
- Apply same port restriction to network gateway bypass
- Add IPv4 format validation for dynamically resolved IPs before
  using them in iptables rules
- Mount chroot-hosts as read-only (:ro) since host.docker.internal
  is pre-injected by docker-manager.ts before mounting

The NAT RETURN rule (which prevents DNAT to Squid) is unchanged,
so MCP traffic still bypasses Squid correctly. Non-allowed port
traffic hits the final DROP rule in the FILTER chain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Mossaka Mossaka force-pushed the fix/host-gateway-port-restriction branch from d0fea8c to 12683ac Compare February 6, 2026 23:46
@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Build Test: Java - Results

Project Compile Tests Status
gson N/A FAIL
caffeine N/A FAIL

Overall: FAIL

Error Details

Both projects failed during Maven dependency resolution with SSL/network errors:

Could not transfer artifact from/to central (https://repo.maven.apache.org/maven2): 
Unsupported or unrecognized SSL message

Root Cause: Maven Central repository (repo.maven.apache.org) appears to be blocked or inaccessible through the firewall.

Action Required: Add repo.maven.apache.org to the firewall's allowed domains list to enable Maven dependency downloads.

AI generated by Build Test Java

@github-actions
Copy link
Contributor

github-actions bot commented Feb 6, 2026

Go Build Test Results

Project Download Tests Status
color 1/1 PASS
env 1/1 PASS
uuid 1/1 PASS

Overall: PASS

All Go projects successfully downloaded dependencies and passed tests.

AI generated by Build Test Go

@github-actions
Copy link
Contributor

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

Rust Build Test Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS

All Rust projects built successfully and tests passed.

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

fix: ensure .copilot/logs exists before docker mount
feat: add build-test-dotnet workflow
✅ GitHub MCP merged PRs; ✅ safeinputs-gh PR list
✅ Playwright title; ❌ Tavily search (tool missing)
✅ file write; ✅ bash cat; ✅ discussion comment; ✅ npm ci && npm run build
Overall status: FAIL

AI generated by Smoke Codex

@github-actions
Copy link
Contributor

Chroot Version Comparison Test Results ❌

The chroot mode tests have completed. Here are the runtime version comparisons between the host system and chroot environment:

Runtime Host Version Chroot Version Match?
Python 3.12.12 3.12.3 ❌ NO
Node.js v24.13.0 v20.20.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Test Status: FAILED

The chroot environment is using different versions of Python and Node.js compared to the host system. Only Go versions match between host and chroot.

AI generated by Smoke Chroot

@github-actions
Copy link
Contributor

✅ Java Build Test Results

All Java projects compiled and tested successfully through the AWF firewall!

Project Compile Tests Status
gson 1/1 PASS
caffeine 1/1 PASS

Overall: PASS 🎉

All Maven dependencies were successfully downloaded through the Squid proxy (172.30.0.10:3128) and all tests passed.

AI generated by Build Test Java

Build complete chroot-hosts content in memory, then write atomically
to a securely-created temp directory (fs.mkdtempSync). This satisfies
CodeQL's js/insecure-temporary-file rule by using the recognized
sanitizer for temp file creation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Mossaka Mossaka force-pushed the fix/host-gateway-port-restriction branch from 45cde65 to c375743 Compare February 10, 2026 20:50
Mossaka and others added 2 commits February 10, 2026 20:51
…-restriction-v2

# Conflicts:
#	.github/workflows/build-test-java.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Chroot tests passed! Smoke Chroot - All security and functionality tests succeeded.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

Go Build Test Results

All Go projects tested successfully! ✅

Project Download Tests Status
color 1/1 PASS
env 1/1 PASS
uuid 1/1 PASS

Overall: PASS

AI generated by Build Test Go

@github-actions
Copy link
Contributor

Build Test: Node.js - Results

All Node.js projects tested successfully!

Project Install Tests Status
clsx PASS
execa PASS
p-limit PASS

Overall: PASS

AI generated by Build Test Node.js

@github-actions
Copy link
Contributor

Smoke Test Results - Claude

Recent merged PRs:

  • fix: configure Java proxy via JAVA_TOOL_OPTIONS for Maven builds
  • fix: preserve docker-compose and config files during cleanup

Test Results:

  • ✅ GitHub MCP
  • ✅ Playwright (title: "GitHub · Change is constant. GitHub keeps you ahead. · GitHub")
  • ✅ File writing
  • ✅ Bash tool

Status: PASS

AI generated by Smoke Claude

@github-actions
Copy link
Contributor

🦀 Rust Build Test Results

Project Build Tests Status
fd 1/1 PASS
zoxide 1/1 PASS

Overall: PASS ✅

All Rust projects built and tested successfully.

AI generated by Build Test Rust

@github-actions
Copy link
Contributor

C++ Build Test Results

Project CMake Build Status
fmt PASS
json PASS

Overall: PASS

All C++ projects built successfully.

AI generated by Build Test C++

@github-actions
Copy link
Contributor

Deno Build Test Results

Project Tests Status
oak 1/1 ✅ PASS
std 1/1 ✅ PASS

Overall: ✅ PASS

All Deno tests completed successfully.

AI generated by Build Test Deno

@github-actions
Copy link
Contributor

Smoke Test Results

✅ GitHub MCP: #572, #643
✅ Playwright: github.com title verified
✅ File Write: smoke-test-copilot-21881980221.txt created
✅ Bash: file verified via cat

Status: PASS | cc: @Mossaka

AI generated by Smoke Copilot

@github-actions
Copy link
Contributor

GitHub MCP merged PRs: ✅ fix: configure Java proxy via JAVA_TOOL_OPTIONS for Maven builds | fix: ensure .copilot/logs exists before docker mount
safeinputs-gh PR list: ✅ fix: use lowercase discussion categories to restore create_discussion tool | fix: restrict /proc/self/environ and docker-compose.yml secret exposure
Playwright title check: ✅
Tavily search: ❌
File write: ✅
Bash cat: ✅
Discussion comment: ✅
Build (npm ci && npm run build): ✅
Overall: FAIL

AI generated by Smoke Codex

@github-actions
Copy link
Contributor

Chroot Version Comparison Test Results

Runtime Host Version Chroot Version Match?
Python 3.12.12 3.12.3 ❌ NO
Node.js v24.13.0 v20.20.0 ❌ NO
Go go1.22.12 go1.22.12 ✅ YES

Overall: ❌ Not all versions match (1/3 passed)

The chroot mode successfully accessed the host Go installation, but Python and Node.js versions differ between the host and chroot environments.

AI generated by Smoke Chroot

@github-actions
Copy link
Contributor

✅ Build Test: Java - PASSED

All Java projects compiled and tested successfully through the AWF firewall.

Project Compile Tests Status
gson 1/1 PASS
caffeine 1/1 PASS

Overall: PASS

Configuration

  • Maven proxy configured via ~/.m2/settings.xml
  • Proxy: 172.30.0.10:3128
  • Dependencies downloaded from Maven Central through Squid proxy

AI generated by Build Test Java

@github-actions
Copy link
Contributor

.NET Build Test Results

Project Restore Build Run Status
hello-world PASS
json-parse PASS

Overall: PASS

All .NET projects built and ran successfully.

AI generated by Build Test .NET

@Mossaka Mossaka merged commit 70d79e9 into main Feb 10, 2026
98 of 99 checks passed
@Mossaka Mossaka deleted the fix/host-gateway-port-restriction branch February 10, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants