[Security Review] π Daily Security Review β gh-aw-firewall (2026-07-12) #6126
Closed
Replies: 1 comment
|
This discussion was automatically closed because it expired on 2026-07-19T07:47:20.101Z.
|
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-firewallcodebase demonstrates a mature, defense-in-depth security posture with multiple overlapping control layers: iptables NAT/filter chains, Squid L7 domain ACLs, capability drops, seccomp (deny-by-default), DLP scanning, workdir tmpfs overlays, and/proccredential isolation. No 0-day vulnerabilities or critical injection flaws were found.npm auditreturns zero CVEs. The primary residual risks are architectural trade-offs (AppArmor disabled for mount support, DinD socket exposure) rather than implementation bugs.Key Metrics:
SCMP_ACT_ERRNO)π Findings from Firewall Escape Test
The pre-fetched escape test summary (
/tmp/gh-aw/escape-test-summary.txt) was empty β no escape test results were available for this review cycle. The analysis below is based entirely on static code analysis and evidence gathered from the live repository.π‘οΈ Architecture Security Analysis
Network Security Assessment
Two-layer enforcement model (
containers/agent/setup-iptables.sh,src/host-iptables-rules.ts):Evidence β default-deny filter chain (
setup-iptables.sh:482β498):Evidence β dangerous port NAT blacklist (
src/squid/policy-manifest.ts):IPv6 bypass mitigation (
src/host-iptables-rules.ts:89β91):Fail-secure: if
ip6tablesis absent, IPv6 is disabled at sysctl level.HTTP proxy visibility gap (documented design choice in
containers/agent/README):http_proxy(lowercase) is intentionally not set. On Ubuntu 22.04,curlignores uppercaseHTTP_PROXYfor HTTP (httpoxy mitigation), so HTTP falls through to iptables DNAT β Squid. This is by design and works correctly, but proxy-unaware tools making HTTP requests may produce non-obvious errors for operators debugging blocked requests.Container Security Assessment
Capability model (
src/services/agent-service.ts:77β93):cap_drop: ALLEvidence β capsh drop (
containers/agent/entrypoint.sh:401β404):AWF_CHROOT_ENABLED=trueis always set (src/services/agent-environment/api-proxy-environment.ts:42), so caps are always dropped.Seccomp profile (
containers/agent/seccomp-profile.json):defaultAction: SCMP_ACT_ERRNOβ deny-by-default with explicit syscall allowlist. Confirmed by test:seccomp-profile.test.ts.AppArmor unconfined (
src/services/agent-service.ts:93):Docker's default AppArmor profile blocks
mount(2). AWF needsSYS_ADMIN+ mount to establish procfs at/host/procwithhidepid=2. AppArmor is set tounconfinedto permit this. Mitigated: SYS_ADMIN is dropped via capsh before user code runs, so user code cannot remount. Seccomp profile provides the remaining syscall guard.workDir tmpfs overlay (
src/services/agent-service.ts:46β55) β prevents agent from readingdocker-compose.yml(which contains API tokens as env vars):/proccredential isolation (containers/agent/entrypoint.sh:509β520):Procfs mounted with
hidepid=2at/host/proc.unset_sensitive_tokens()clears 16 credential env vars before exec. Therun_agent_with_token_protectionfunction launches the agent in background, unsets tokens, then waits β closing the/proc/1/environrace window.Domain Validation Assessment
Squid injection prevention (
src/domain-validation.ts:23):Blocks whitespace (line injection), null bytes, quotes, semicolons, backticks, hash (comment injection).
Domain names additionally reject backslash (
/[\s\0"';#\]/) to block regex injection. URL patterns (for--allow-urls`) allow backslash intentionally for regex escaping.ReDoS prevention (
src/domain-patterns.ts:66):Wildcard
*is converted to a character class, not.*, preventing catastrophic backtracking in Squid's regex engine.Over-broad pattern rejection (
src/domain-validation.ts:49β62):*,*.*, and any pattern of only*/.are rejected. Patterns with too many wildcard segments (β₯ totalSegments-1) also rejected.Input Validation Assessment
--allow-host-ports: Validated twice β in TypeScript (parseValidPortSpecs) and in shell (split_valid_port_specsin setup-iptables.sh). Dangerous ports blocked even with explicit user request (src/squid/validation.ts:validateAndSanitizeHostAccessPort).--agent-image: Restricted to approved patterns only (src/domain-utils.ts:SAFE_BASE_IMAGE_PATTERNS) β official Ubuntu, catthehacker runner images, or SHA256-pinned. Prevents supply chain attacks via custom base images without--build-local.Port specification leading-zero rejection (
setup-iptables.sh:27): Rejects080to prevent octal interpretation, aligned with TypeScriptisValidPortSpec().entrypoint.sh, ~startup secondsagent-service.ts:93--allow-urlspatternsdomain-matchers.ts:parseUrlPatterns--enable-dind) grants full container escapesrc/dind-bootstrap.tsAWF_ALLOW_HOST_PORTSenv var fallback without strict validation if container/CLI version mismatchsetup-iptables.sh:409AWF_VALID_ALLOW_HOST_PORTSpreferred; shell secondary validation presentpolicy-manifest.ts:DANGEROUS_PORTS--allow-host-portsrequiredssl-bump.ts:usingTmpfsupstream-proxy.tssetup-iptables.sh:477setup-iptables.shπ― Attack Surface Map
--allow-domainsCLI βvalidateDomainOrPattern()βsquid.conf--allow-urlsCLI βparseUrlPatterns()β Squidurl_regexassertSafeForSquidConfigapplied, backslash allowed for regex escapingOUTPUTchain172.30.0.10:3128/proc/1/environ,docker-compose.yml, SSL CA key--enable-dindβ/var/run/docker.sockbind mount--enable-host-access+--allow-host-ports--agent-imagecustom value--build-localrequiredπ Evidence Collection
Command: npm audit
Command: grep for SYS_ADMIN/cap_add/cap_drop patterns
Command: grep for AWF_CHROOT_ENABLED
Command: grep for dangerous ports
Command: seccomp profile default action
Command: Squid injection char validation
β Recommendations
π΄ High Priority
H1 β Document and gate DinD socket exposure risk (
src/dind-bootstrap.ts, CLI--enable-dind)The Docker socket bind-mount is a full container escape vector. Consider adding a mandatory acknowledgment flag (e.g.,
--enable-dind-i-understand-the-risk) or a prominent runtime warning when--enable-dindis used in non-CI contexts. Current documentation notes the risk but there is no runtime friction.H2 β Harden dangerous-port list: add Docker API and common dev-server ports
Port 2375 (Docker API unencrypted), 2376 (Docker API TLS), 8080, 8443, 9090 (Prometheus), 4040 are absent from
DANGEROUS_PORTS. An agent aware of the host network could reach these services via--enable-host-access.File:
src/squid/policy-manifest.tsπ‘ Medium Priority
M1 β AppArmor custom profile instead of unconfined (
src/services/agent-service.ts:93)Currently
apparmor:unconfineddisables Docker's AppArmor guard. A narrow custom AppArmor profile that allows only the specificmountcall needed for procfs (typeproc, flagshidepid=2) would restore AppArmor as a defense-in-depth layer without blocking SYS_ADMIN+mount. This is non-trivial but would eliminate the AppArmor coverage gap.M2 β SYS_ADMIN window explicit test (
entrypoint.sh)Add an integration test that verifies
SYS_ADMINis absent from/proc/self/statuscapabilities after the agent process starts. This guards against regressions wherecapshis skipped (e.g.,AWF_CHROOT_ENABLEDnot being set).M3 β Rate-limit tuning for LOG rules (
setup-iptables.sh:477)The LOG rules use
--limit 5/min --limit-burst 10. A short burst attack (e.g., 100 connection attempts in 1 second) would only log the first 10, leaving 90 attempts invisible in audit logs. Consider raising burst to 50 or adding per-IP rate limiting with--hashlimit.M4 β SSL Bump CA key fallback logging (
src/ssl-bump.ts)When tmpfs mount fails (common in non-root environments), the CA key falls back to disk with only a
logger.debugmessage. Raise tologger.warnto ensure operators are notified that key material is on disk.π’ Low Priority
L1 β
--allow-urlsregex complexity limitUser-supplied URL patterns accepted by
--allow-urlscould include high-complexity regexes that stress Squid's POSIX regex engine. Add a maximum length check (e.g., 500 chars) and reject patterns containing recursive constructs ((?:...), lookahead, etc.) that are not needed for URL matching.L2 β
AWF_ALLOW_HOST_PORTSfallback removalsetup-iptables.sh:409falls back to unvalidatedAWF_ALLOW_HOST_PORTSifAWF_VALID_ALLOW_HOST_PORTSis absent (version mismatch scenario). Consider emitting a clear error and aborting rather than processing potentially unvalidated port specs.L3 β HTTP traffic operator visibility
The intentional omission of
http_proxy(httpoxy mitigation) means HTTP-blocked requests produce a different error UX than HTTPS-blocked requests. Add a startup log message explaining this so operators don't misdiagnose HTTP blocks as infrastructure failures.π Security Metrics
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
awmgmcpgSee Network Configuration for more information.
All reactions