fix: use Docker default allowlist seccomp profile#1068
Conversation
Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com>
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (1 files)
Coverage comparison generated by |
There was a problem hiding this comment.
Pull request overview
This PR addresses a critical security finding (H-1) by replacing the custom seccomp profile with Docker's built-in default allowlist-based profile. The custom profile used SCMP_ACT_ALLOW (blocklist) as the default action, blocking only ~28 syscalls across 3 groups, leaving ~280+ dangerous syscalls accessible. Docker's default profile uses SCMP_ACT_ERRNO (allowlist) and blocks ~44 dangerous syscall families, providing significantly stronger protection.
Changes:
- Removed custom
containers/agent/seccomp-profile.jsonfile that used a weak blocklist approach - Removed seccomp configuration from
docker-manager.tsto use Docker's default profile automatically - Updated tests to verify no custom seccomp profile is configured
- Removed seccomp file from pkg.assets in package.json
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/docker-manager.ts |
Removed custom seccomp configuration and added comprehensive comments explaining Docker's default profile and the layered security model (capabilities + seccomp) |
src/docker-manager.test.ts |
Updated test to verify no custom seccomp profile is configured and added explanatory comments about Docker's default profile |
package.json |
Removed containers/agent/seccomp-profile.json from pkg assets array |
containers/agent/seccomp-profile.json |
Deleted the weak blocklist-based custom seccomp profile |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Smoke Test Results — Run 22499024993 ✅ GitHub MCP — Last 2 merged PRs:
✅ Playwright — github.com title contains "GitHub" Overall: PASS
|
🟢 Build Test: Node.js — PASS
Overall: PASS
|
C++ Build Test Results
Overall: PASS
|
Smoke Test Results
Overall: PASS
|
🦀 Rust Build Test Results
Overall: ✅ PASS
|
Go Build Test Results
Overall: PASS ✅
|
Deno Build Test Results
Overall: ✅ PASS
|
|
PR titles: fix: add explicit execute directive to smoke-codex to prevent noop; fix(deps): resolve high-severity rollup vulnerability in docs-site
|
🧪 Bun Build Test Results
Overall: ✅ PASS Bun version:
|
.NET Build Test Results
Overall: PASS Run outputhello-world:
|
Java Build Test Results
Overall: PASS ✅
|
Chroot Version Comparison Results
Overall: ❌ Not all versions matched — Python and Node.js versions differ between host and chroot environments.
|
Security review finding H-1: the custom seccomp profile used
SCMP_ACT_ALLOW(blocklist) as default action, only blocking 3 syscall groups (~28 syscalls) while leaving ~280+ dangerous syscalls accessible.Replaced with Docker's built-in default seccomp profile which uses
SCMP_ACT_ERRNO(allowlist), blocking ~44 dangerous syscall families. This is the approach recommended in the security review as the alternative option.Changes
containers/agent/seccomp-profile.json— custom blocklist profile no longer neededseccomp=fromsecurity_optindocker-manager.ts— Docker automatically applies its default allowlist profile when no custom profile is specifiedwriteConfigs()andpkg.assetsWhy Docker's default is sufficient
The container's existing capability model already enforces the needed restrictions:
cap_drop: ['SYS_PTRACE']— blocked at capability level even though Docker's default allows on kernel ≥ 4.8CAP_SYS_ADMIN;capsh --dropirrevocably removes it before user codeCAP_SYS_CHROOT; also dropped viacapshno-new-privileges:trueunchangedOriginal prompt
This section details on the original issue you should resolve
<issue_title>[Security Review] Daily Security Review and Threat Model — 2026-02-26</issue_title>
<issue_description>## 📊 Executive Summary
This review covers a deep, evidence-based security analysis of the
gh-aw-firewallcodebase. The architecture is well-designed and layered; no critical bypass that works by default was found. However, several medium-to-high-severity gaps were identified that could weaken the security guarantee under specific conditions or configurations.🔍 Findings from Previous Security Testing
The
security-reviewworkflow was queried but log download was unavailable for this run. The analysis below is based entirely on direct codebase inspection.🛡️ Architecture Security Analysis
Network Security Assessment
Evidence — iptables rule ordering (
containers/agent/setup-iptables.sh):The NAT OUTPUT chain processes rules in order:
The filter chain ends with:
The container
setup-iptables.shonly applies NAT rules for IPv6 DNS, but never adds a default DROP for IPv6 TCP traffic. Ifip6tablesis unavailable (common on some hosts), IPv6 TCP connections are neither redirected to Squid nor dropped. A process inside the container could make direct IPv6 TCP connections to the internet, bypassing domain whitelisting entirely.The host-level chain (
FW_WRAPPER_V6) also has a conditional gate:If no IPv6 DNS servers are configured (the default), the
FW_WRAPPER_V6chain is never created, and IPv6 egress from containers on the bridge is unfiltered at the host level.--ipv6=falseNo
--ipv6=falseflag is passed. If the Docker daemon has IPv6 enabled globally ("ipv6": truein/etc/docker/daemon.json), containers onawf-netwill receive an IPv6 address and can initiate IPv6 connections. Combined with NW-1, this is a potential bypass path.✅ DNS exfiltration prevention is solid. Both the host chain and container iptables only allow DNS to explicitly whitelisted servers. UDP is blocked globally after DNS ACCEPT rules.
Container Security Assessment
The three blocked groups are:
ptrace,process_vm_readv,process_vm_writev(process inspection)kexec_load,reboot,init_module,delete_module,add_key,keyctl, ... (kernel/system)umount,umount2(unmount)Docker's default seccomp profile blocks ~44 syscall families. This custom profile only blocks 3 groups, leaving dangerous syscalls like
clone(namespace creation),unshare,setns,mknod,mount(allowed!), and many others accessible. An attacker who escapes the capability drop could use these syscalls for privilege escalation or container escape.Specific concern:
mountis explicitly allowed (per the comment: "mount is allowed for procfs but unmount is not needed"). OnceCAP_SYS_ADMINis dropped before user code runs, mount should fail anyway — but the seccomp profile itself is not enforcing this boundary.✅ Capability drop is correctly implemented (
containers/agent/entrypoint.shline ~6...💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.