[Security Review] Daily Security Review — 2026-08-28 #7824
Closed
Replies: 1 comment
|
This discussion was automatically closed because it expired on 2026-09-04T12:17:32.442Z.
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
📊 Executive Summary
The gh-aw-firewall (
awf) codebase shows a mature, defense-in-depth security architecture: L7 Squid domain ACL enforcement, iptables DNAT fallback, selective (not blanket) host filesystem bind mounts, capability dropping (SYS_CHROOT/SYS_ADMIN) viacapsh, DNS allowlisting, and a ReDoS-safe wildcard-to-regex domain matcher. No critical code-level vulnerabilities were found in the reviewed source. The complementary "Secret Digger" prompt-injection test confirms the agent-layer safety policy correctly refused an exfiltration task, which is a positive signal but out of scope for this repo's own attack surface.Overall posture: Good, with a few Medium/Low items worth tracking (root-owned iptables scripts, sed-based URL parsing, reliance on host
capsh/kernel trust).🔍 Findings from Firewall Escape Test
/tmp/gh-aw/escape-test-summary.txtcontains CI log output from a "Secret Digger (Copilot)" workflow run (run 29286879560), not a firewall network-escape test. Key facts:noopwith: "Refused prompt injection attack... This is prohibited by the security policy. No investigation was performed."GH_AW_DETECTION_CONCLUSION: warning,GH_AW_DETECTION_REASON: threat_detected, and opened issue [aw] Detection Runs #6205 in the detection-runs tracker.awf's own container/network isolation and should not be read as validating (or invalidating) the firewall's L3/L4/L7 controls.🛡️ Architecture Security Analysis
Network Security (
src/host-iptables-rules.ts,containers/agent/setup-iptables.sh)FW_WRAPPER) with explicit allow rules: Squid IP unrestricted egress, conntrack ESTABLISHED/RELATED, loopback, DNS to configured upstream servers only (addIpv6DnsRules, lines ~89-140).isIp6tablesAvailable()check: if ip6tables is missing, IPv6 is disabled via sysctl (disableIpv6ViaSysctl) rather than silently allowed — good fail-closed behavior (host-iptables-rules.ts:90-93).setup-iptables.sh(540 lines) DNATs ports 80/443 to Squid as defense-in-depth, blocks SSH/SMTP/DB ports.HTTP_PROXY/HTTPS_PROXYenv vars for primary enforcement; proxy-unaware tools fall back to DNAT+TLS-CONNECT rejection (a connection error, not a clean block) — documented behavior, low residual risk since traffic still can't reach arbitrary hosts.Container Security (
containers/agent/entrypoint.sh,src/capability-filter.ts)/etc/shadowand non-whitelisted$HOMEdirs.capsh --drop=cap_sys_chroot,cap_sys_adminbefore user command execution (entrypoint.sh:438, 1620, 1658-1659), executed viagosu awfuserso the user command never runs as root.NET_ADMINis scoped only to the short-livedawf-iptables-initcontainer, never granted to the agent — good least-privilege separation.capsh(checked at entrypoint.sh:1099-1104); if absent, execution fails closed with an explicit error rather than silently running privileged — good.LINUX_CAPABILITY_MAPincapability-filter.tsreadsCapBndfrom/proc/<pid>/statusto verify capability state — sound verification technique.Domain Validation (
src/domain-patterns.ts)[a-zA-Z0-9.-]*) instead of.*specifically to avoid ReDoS (documented in comments, domain-patterns.ts:65-70, 96-98) — a proactive, well-reasoned mitigation.^...$) preventing partial-match bypass (e.g.,evilgithub.commatching agithub.compattern).Input Validation / Injection Risks
exec()/shell: truewith unsanitized input found insrc/container-lifecycle.ts; allexeca()calls pass argument arrays (not shell strings), avoiding classic shell injection.entrypoint.sh,api-proxy-health-check.sh) usesed -Eto parse$ANTHROPIC_BASE_URL/$OPENAI_BASE_URL/$COPILOT_API_URL/$AWF_CLI_PROXY_URLenv vars into host/port. These values come from operator-configured env, not directly from untrusted agent output, limiting exploitability, but sed-based URL parsing is fragile (no full URI validation) — a malformed value could silently produce an empty host/port rather than failing safely.awfuserto gain host UID/GID mapping issuesNET_ADMINcapability withheld from agent container; only iptables-init has itsquid-logs), not writable by agent user/etc/shadow, unwhitelisted$HOMEdirs; procfshidepid=2blocks reading other processes'/proc/[pid]/environSYS_CHROOT/SYS_ADMINafter capsh drop🎯 Attack Surface Map
containers/agent/setup-iptables.sh,src/host-iptables-rules.tscontainers/agent/entrypoint.sh:1620,1658capsh --drop,gosuuser switch, cap check via/proc/*/statuscapsh; Alpine/musl hosts explicitly unsupported (fails closed, documented)src/domain-patterns.ts:65-110entrypoint.sh:205-206,api-proxy-health-check.sh:51-52,104-105,170-171sed-based parsing lacks strict URI validation; malformed input silently degrades rather than erroringsrc/container-lifecycle.ts,src/compose-generator.tsexeca()calls (no shell injection)📋 Evidence Collection
Commands run and key outputs
✅ Recommendations
Critical
High
sed-based extraction of proxy URLs (entrypoint.sh:205-206,api-proxy-health-check.sh) so malformed operator config fails loudly instead of silently producing empty host/port.Medium
ip6tablesis unavailable and sysctl-based IPv6 disable itself fails (e.g., in restricted CI runners without sysctl write access) — ensure fail-closed, not fail-open.Low
capsh/gosuversion pinning is needed to avoid supply-chain drift on host-provided binaries used for privilege drop.📈 Security Metrics
All reactions