You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This review analyzed 8,179 lines of security-critical code across 9 files covering network egress filtering, container hardening, domain validation, and credential protection. The overall security posture is strong, with multiple defense-in-depth layers. No critical vulnerabilities were identified. Three medium findings and two low findings were discovered, each with existing partial mitigations.
No Firewall Escape Test agent workflow found (firewall-escape-test not in workflow inventory). The closest related workflows are secret-digger-* (hourly) and security-guard (per PR). This review is self-contained.
🔍 Escape Test Agent Report
No dedicated firewall-escape-test workflow exists in the repository. The security-review workflow (security-review.md) itself IS this daily report. Secret digger workflows (claude, codex, copilot) run hourly and attempt to detect accidental credential exposure.
🛡️ Architecture Security Analysis
Network Security Assessment
STRONG — Dual-layer egress control with defense-in-depth.
The system implements two independent firewall layers:
Host layer (src/host-iptables.ts): DOCKER-USER → FW_WRAPPER chain enforces allowlist-only egress for all containers on the awf-net (172.30.0.0/24) bridge. Rules verified at lines 316, 489–530.
Container layer (containers/agent/setup-iptables.sh): NAT DNAT redirects all port 80/443 traffic to Squid:3128. Falls through to TCP/UDP DROP default deny.
Evidence:
# Host layer - default deny in FW_WRAPPER# src/host-iptables.ts:519-530
await execa('iptables', ['-t', 'filter', '-A', CHAIN_NAME, '-j', 'REJECT', ...]);# Container layer - default deny TCP/UDP# setup-iptables.sh (line ~416-418)
iptables -A OUTPUT -p tcp -j DROP
iptables -A OUTPUT -p udp -j DROP
src/host-iptables.ts: disableIpv6ViaSysctl() when ip6tables unavailable
When ip6tables IS available, a parallel FW_WRAPPER_V6 chain provides equivalent filtering
DNS exfiltration prevention is robust: only whitelisted DNS servers (default: 8.8.8.8, 8.8.4.4) allowed; container resolv.conf points only to Docker embedded DNS (127.0.0.11).
IMDS/metadata endpoint protection: 169.254.0.0/16 explicitly rejected at host layer (src/host-iptables.ts:498) and multicast (224.0.0.0/4) blocked.
⚠️ Finding NET-1 (Medium): ICMP not blocked at container-level iptables
# setup-iptables.sh (end of file)
iptables -A OUTPUT -p tcp -j DROP # TCP blocked
iptables -A OUTPUT -p udp -j DROP # UDP blocked# No explicit ICMP DROP rule
ICMP traffic (protocol 1) bypasses the container-level OUTPUT chain. It is caught by the host-level FW_WRAPPER REJECT rule, but defense-in-depth suggests blocking at both layers. ICMP tunneling tools (e.g., ptunnel-ng) could exploit any gap between host and container filtering.
Container Security Assessment
STRONG — Multiple privilege reduction mechanisms applied in sequence.
NET_ADMIN is never granted to the agent container — iptables setup is handled by the separate awf-iptables-init init container that shares the network namespace. This cleanly separates privilege.
One-shot token library (containers/agent/one-shot-token/one-shot-token.c) intercepts getenv() calls for sensitive tokens, caches on first call, and unsets from /proc/self/environ. XOR-obfuscated token names prevent strings reconnaissance.
⚠️ Finding SEC-1 (Medium): unshare and setns syscalls allowed in seccomp profile
# containers/agent/seccomp-profile.json - Group 0 (SCMP_ACT_ALLOW)# Line 340: "unshare" is in the ALLOW group# Line 276: "setns" is in the ALLOW group```Evidence from analysis:```
Group 0: action=SCMP_ACT_ALLOW, names_count=340
includes_unshare=True, includes_setns=True, includes_mount=True
unshare --user --map-root-user creates a user namespace where the process appears as UID 0. While no-new-privileges:true prevents gaining capabilities, user namespaces have historically been vectors for kernel privilege escalation (CVE-2022-0492, CVE-2021-22555, etc.). setns could allow entering another container's network namespace if the process can access /proc/(pid)/ns/net of a container without proper restrictions.
Mitigations in place: no-new-privileges:true, NET_ADMIN never granted, NET_RAW explicitly dropped. The practical risk is low on patched kernels but represents a non-minimal attack surface.
⚠️ Finding SEC-2 (Low): Non-chroot mode drops no capabilities
# containers/agent/entrypoint.sh:360-364else# In non-chroot mode, no capabilities need to be dropped
CAPS_TO_DROP=""echo"[entrypoint] No capabilities to drop (NET_ADMIN never granted to agent)"fi
In non-chroot mode, cap_sys_chroot and cap_sys_admin are present at runtime since capsh --drop= is a no-op with an empty list. The agent's command inherits these capabilities. While no-new-privileges:true limits further escalation, running with SYS_ADMIN allows mounting operations.
Domain Validation Assessment
STRONG — Comprehensive input validation with defense-in-depth sanitization.
Rejects broad patterns: *, *.*, *.*.* (too many wildcards)
Rejects double-dots, leading/trailing dots
ReDoS prevention: wildcards converted to [a-zA-Z0-9.-]* character class (not .*)
Domain length limit of 512 chars in isDomainMatchedByPattern()
assertSafeForSquidConfig() re-validates before Squid config interpolation (src/squid-config.ts:64):
if(SQUID_DANGEROUS_CHARS.test(value)){thrownewError('SECURITY: Domain or pattern contains characters unsafe for Squid config...');}
⚠️ Finding DOMAIN-1 (Medium): subdomains: false in YAML rulesets has no effect
// src/rules.ts:117-153 - expandRule() ignores the subdomains fieldexportfunctionexpandRule(rule: Rule): string[]{// Always returns bare domain; subdomain matching is always enabledreturn[rule.domain];}
Squid config always adds subdomain matching for plain domains (src/squid-config.ts:73-79). A user who creates a ruleset with subdomains: false expecting exact-match-only behavior will unknowingly allow all subdomains. This is documented in code comments but the API contract is misleading.
Example: A ruleset entry { domain: "internal.example.com", subdomains: false } still allows evil.internal.example.com in Squid ACL.
Input Validation Assessment
STRONG — User command passed via Docker CMD array (no shell interpolation).
The user command goes through src/cli.ts → src/docker-manager.ts as a Docker CMD array, not shell expansion. escapeShellArg() (src/cli.ts:938-951) properly single-quotes arguments.
⚠️ Finding INJ-1 (Low): AWF_HOST_PATH interpolated unquoted into shell heredoc
# containers/agent/entrypoint.sh:599-603
cat >"/host\$\{SCRIPT_FILE}"<<AWFEOF # Unquoted heredoc - expands variables#!/bin/bashexport PATH="\$\{AWF_HOST_PATH}" # ← unquoted interpolationAWFEOF````AWF_HOST_PATH` comes from the host's `$PATH` variable merged with `$GITHUB_PATH` entries (`src/docker-manager.ts:591`). If PATH contains `"` or `$(...)` sequences (atypical but possible on custom runners), this would result in shell injection within the generated script file inside the container. The risk is low in practice because PATH values are operator-controlled and rarely contain shell metacharacters.---## ⚠️ Threat Model (STRIDE)| ID | Category | Threat | Evidence | Likelihood | Impact | Mitigation Status ||----|----------|--------|----------|------------|--------|-------------------|| T1 | **Information Disclosure** | DNS exfiltration via non-whitelisted resolver | UDP port 53 to non-whitelisted IPs blocked at both layers | Low | High | ✅ Mitigated || T2 | **Elevation of Privilege** | User namespace escape via `unshare -U` | `unshare` in seccomp ALLOW (line 340) | Low | High | ⚠️ Partial — `no-new-privileges` limits but doesn't eliminate || T3 |**Information Disclosure**| ICMP tunneling (ptunnel-ng) | No ICMP DROP in container OUTPUT chain | Low | Medium | ⚠️ Partial — blocked at host FW_WRAPPER || T4 |**Tampering**| Squid config injection via domain names |`validateDomainOrPattern` + `assertSafeForSquidConfig`| Very Low | High | ✅ Mitigated || T5 |**Elevation of Privilege**| Docker-in-Docker firewall bypass |`--enable-dind` mounts Docker socket; explicitly documented | Medium (if enabled) | Critical | ⚠️ By design; warning shown || T6 |**Information Disclosure**| Token leakage via `/proc/self/environ`| one-shot-token LD_PRELOAD + `unset_sensitive_tokens()`| Low | High | ✅ Mitigated || T7 |**Spoofing**| Subdomain bypass via `subdomains: false` misunderstanding |`expandRule()` always enables subdomain matching | Low | Medium | ⚠️ API contract misleading || T8 |**Information Disclosure**| SSL Bump CA key compromise | CA key in`/tmp/awf-(ts)/`; read-only during run | Very Low | High | ✅ Mitigated (session-scoped CA) || T9 |**Denial of Service**| Process fork bomb |`pids_limit: 1000`| Low | Medium | ✅ Mitigated || T10 |**Repudiation**| Insufficient audit logging | iptables LOG + Squid access.log with custom format | Low | Low | ✅ Comprehensive logging || T11 |**Elevation of Privilege**| SYS_ADMIN retained in non-chroot mode | capsh drops nothing when `CAPS_TO_DROP=""`| Medium | Medium | ⚠️ Partial — NET_ADMIN never granted |---## 🎯 Attack Surface Map| Entry Point | File:Line | What it does | Current Protections | Risk ||-------------|-----------|-------------|-------------------|------||`--allow-domains`| cli.ts:1222, domain-patterns.ts | Domain whitelist input | validateDomainOrPattern, SQUID_DANGEROUS_CHARS |**Low**||`--allow-urls`| cli.ts:1222, squid-config.ts:172 | URL regex allowlist (SSL bump) | assertSafeForSquidConfig |**Low**|| User command (args) | cli.ts:1422, docker-manager.ts | Command executed in container | Passed as CMD array, escapeShellArg |**Low**||`--env` passthrough | cli.ts:1272, docker-manager.ts:596 | Custom env vars to container | KEY=VALUE format validation; excludes PATH/HOME |**Low**||`--ruleset-file`| cli.ts, rules.ts | YAML domain rules from file | loadRuleSet validation + validateDomainOrPattern |**Low**|| Container network egress | setup-iptables.sh, host-iptables.ts | All outbound TCP/UDP | Dual-layer NAT+filter; Squid ACL; dangerous port blocklist |**Low**||`unshare` syscall | seccomp-profile.json:340 | Namespace creation | no-new-privileges; cap_drop; patched kernel |**Medium**||`mount` syscall | seccomp-profile.json:175, entrypoint.sh:416 | Filesystem mount | SYS_ADMIN dropped via capsh before user code |**Low**|| Agent self-bypass | setup-iptables.sh | Traffic to own IP skips Squid | Loopback rule needed fortest frameworks |**Low**||`--enable-dind`| cli.ts:1334, docker-manager.ts:980 | Docker socket access | Explicit user opt-in; documented bypass risk |**High (if used)**||`--ssl-bump`| cli.ts, squid-config.ts:140 | TLS interception | Session-scoped CA; agent trusts CA via NODE_EXTRA_CA_CERTS |**Medium**|---## 📋 Evidence Collection<details><summary>Command 1: Seccomp profile analysis</summary>```
python3 -c "import jsonwith open('containers/agent/seccomp-profile.json') as f: d = json.load(f)print('defaultAction:', d.get('defaultAction'))for i, g in enumerate(d.get('syscalls', [])): print(f'Group {i}: action={g[\"action\"]}, includes_unshare={\"unshare\" in g[\"names\"]}, includes_setns={\"setns\" in g[\"names\"]}')"
defaultAction: SCMP_ACT_ERRNO
Group 0: action=SCMP_ACT_ALLOW, names_count=340, includes_unshare=True, includes_setns=True
Group 1: action=SCMP_ACT_ALLOW, names_count=3
Group 2: action=SCMP_ACT_ERRNO, includes_ptrace=True # ptrace EXPLICITLY BLOCKED
Group 3: action=SCMP_ACT_ERRNO # kexec, reboot, init_module, etc.
Group 4: action=SCMP_ACT_ERRNO # umount, umount2```</details><details><summary>Command 2: Container capabilities</summary>```
grep -n "cap_drop\|cap_add\|security_opt" src/docker-manager.ts
# Agent container:
cap_add: ['SYS_CHROOT', 'SYS_ADMIN'],
cap_drop: ['NET_RAW', 'SYS_PTRACE', 'SYS_MODULE', 'SYS_RAWIO', 'MKNOD'],
security_opt: ['no-new-privileges:true', 'seccomp:...', 'apparmor:unconfined'],
# iptables init container:
cap_add: ['NET_ADMIN', 'NET_RAW'],
cap_drop: ['ALL'], # then adds back only what's needed```</details><details><summary>Command 3: ICMP gap verification</summary>```# setup-iptables.sh - final OUTPUT chain rules
iptables -A OUTPUT -p tcp -j DROP # TCP blocked
iptables -A OUTPUT -p udp -j DROP # UDP blocked# No: iptables -A OUTPUT -p icmp -j DROP# ICMP passes container OUTPUT chain, caught by host FW_WRAPPER REJECT
Command 4: subdomains field no-op
// src/rules.ts:117-153exportfunctionexpandRule(rule: Rule): string[]{// Always returns bare domain regardless of subdomains fieldreturn[rule.domain];}// Comment: "The existing system already handles subdomain matching when a plain domain is provided"// But this is always true - subdomains:false has no effect```</details><details><summary>Command 5: npm audit</summary>```npmaudit--jsonCritical/Highvulns: []
Total: {'info': 0,'low': 0,'moderate': 0,'high': 0,'critical': 0,'total': 0}
✅ Zero known dependency vulnerabilities.
✅ Recommendations
🔴 Critical
None found.
🟠 High
None found.
🟡 Medium
M1 — Block ICMP at container-level iptables (Finding NET-1)
Add an explicit ICMP DROP rule to containers/agent/setup-iptables.sh before the final TCP/UDP drops:
# After the existing DNS allow rules, before TCP/UDP DROP:
iptables -A OUTPUT -p icmp -j DROP
This closes the ICMP covert channel (ptunnel-ng) at the container level as a defense-in-depth measure, rather than relying solely on the host FW_WRAPPER chain.
M2 — Remove or restrict unshare and setns from seccomp ALLOW (Finding SEC-1)
In containers/agent/seccomp-profile.json, move unshare and setns to the SCMP_ACT_ERRNO group (Group 3), or add conditions (e.g., only allow unshare with non-CLONE_NEWUSER flags via seccomp arg filtering):
{
"names": ["unshare", "setns"],
"action": "SCMP_ACT_ERRNO",
"comment": "Block namespace creation/entry - not needed for development tools"
}
Verify this doesn't break JVM, .NET CLR, or container runtimes that use unshare for sandboxing their own processes.
M3 — Fix subdomains: false YAML ruleset field to actually work (Finding DOMAIN-1)
In src/rules.ts, implement the intended behavior:
exportfunctionexpandRule(rule: Rule): string[]{if(rule.subdomains===false){// Pass with exact: prefix to trigger exact-match-only mode in Squidreturn[`exact:\$\{rule.domain}`];}return[rule.domain];}
And update src/squid-config.ts to generate dstdomain exact.com (without leading dot) for exact-match entries. Until fixed, add a warning in the CLI when a ruleset contains subdomains: false.
🔵 Low
L1 — Quote AWF_HOST_PATH interpolation in heredoc (Finding INJ-1)
In containers/agent/entrypoint.sh, use a quoted heredoc for the PATH line to prevent variable expansion:
# Current (unquoted heredoc - expands variables):
cat >"/host\$\{SCRIPT_FILE}"<<AWFEOFexport PATH="\$\{AWF_HOST_PATH}"AWFEOF# Better: validate/sanitize AWF_HOST_PATH before interpolation# Or use printf to write the line separately after the quoted heredoc
Alternatively, validate AWF_HOST_PATH in src/docker-manager.ts to reject values containing shell metacharacters.
L2 — Drop SYS_ADMIN in non-chroot mode too (Finding SEC-2)
Even in non-chroot mode, SYS_ADMIN capability is not needed after container initialization. Consider removing it from cap_add when chroot is not requested, or explicitly dropping it in the non-chroot path:
# non-chroot mode:
CAPS_TO_DROP="cap_sys_chroot,cap_sys_admin"# same as chroot mode
This reduces the blast radius if another container escape mechanism is found.
📈 Security Metrics
Metric
Value
Lines of security-critical code analyzed
8,179
Attack surfaces identified
11
STRIDE threat categories covered
6/6
Critical vulnerabilities
0
High vulnerabilities
0
Medium findings
3
Low findings
2
Known dependency CVEs
0
Defense-in-depth layers (network)
2 (container + host)
Defense-in-depth layers (credential)
3 (one-shot token + unset + API proxy)
Test coverage (npm test)
Passing, 0 CVEs
🏅 Notable Security Strengths
NET_ADMIN never granted to agent — iptables init container pattern is elegant and correct
one-shot-token LD_PRELOAD with XOR-obfuscated token names prevents /proc/self/environ exposure
ptrace explicitly ERRNO'd in both seccomp (Group 2) and cap_drop (SYS_PTRACE) — double-blocked
Docker socket hidden by default via /dev/null bind mount — DinD requires explicit opt-in
Dangerous port blocklist (SSH 22, SMTP 25, databases) at both NAT and filter layers
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
📊 Executive Summary
This review analyzed 8,179 lines of security-critical code across 9 files covering network egress filtering, container hardening, domain validation, and credential protection. The overall security posture is strong, with multiple defense-in-depth layers. No critical vulnerabilities were identified. Three medium findings and two low findings were discovered, each with existing partial mitigations.
No Firewall Escape Test agent workflow found (
firewall-escape-testnot in workflow inventory). The closest related workflows aresecret-digger-*(hourly) andsecurity-guard(per PR). This review is self-contained.🔍 Escape Test Agent Report
No dedicated firewall-escape-test workflow exists in the repository. The security-review workflow (
security-review.md) itself IS this daily report. Secret digger workflows (claude, codex, copilot) run hourly and attempt to detect accidental credential exposure.🛡️ Architecture Security Analysis
Network Security Assessment
STRONG — Dual-layer egress control with defense-in-depth.
The system implements two independent firewall layers:
src/host-iptables.ts):DOCKER-USER → FW_WRAPPERchain enforces allowlist-only egress for all containers on theawf-net(172.30.0.0/24) bridge. Rules verified at lines 316, 489–530.containers/agent/setup-iptables.sh): NAT DNAT redirects all port 80/443 traffic to Squid:3128. Falls through to TCP/UDP DROP default deny.Evidence:
IPv6 is disabled at both layers:
setup-iptables.sh:sysctl -w net.ipv6.conf.all.disable_ipv6=1(line 48)src/host-iptables.ts:disableIpv6ViaSysctl()when ip6tables unavailableFW_WRAPPER_V6chain provides equivalent filteringDNS exfiltration prevention is robust: only whitelisted DNS servers (default: 8.8.8.8, 8.8.4.4) allowed; container resolv.conf points only to Docker embedded DNS (127.0.0.11).
IMDS/metadata endpoint protection:
169.254.0.0/16explicitly rejected at host layer (src/host-iptables.ts:498) and multicast (224.0.0.0/4) blocked.ICMP traffic (protocol 1) bypasses the container-level OUTPUT chain. It is caught by the host-level FW_WRAPPER REJECT rule, but defense-in-depth suggests blocking at both layers. ICMP tunneling tools (e.g.,
ptunnel-ng) could exploit any gap between host and container filtering.Container Security Assessment
STRONG — Multiple privilege reduction mechanisms applied in sequence.
Container security configuration (
src/docker-manager.ts:1195-1220):SYS_CHROOTandSYS_ADMINare dropped viacapshbefore user code runs (entrypoint.sh:357-760):NET_ADMINis never granted to the agent container — iptables setup is handled by the separateawf-iptables-initinit container that shares the network namespace. This cleanly separates privilege.One-shot token library (
containers/agent/one-shot-token/one-shot-token.c) interceptsgetenv()calls for sensitive tokens, caches on first call, and unsets from/proc/self/environ. XOR-obfuscated token names preventstringsreconnaissance.unshareandsetnssyscalls allowed in seccomp profileunshare --user --map-root-usercreates a user namespace where the process appears as UID 0. Whileno-new-privileges:trueprevents gaining capabilities, user namespaces have historically been vectors for kernel privilege escalation (CVE-2022-0492, CVE-2021-22555, etc.).setnscould allow entering another container's network namespace if the process can access/proc/(pid)/ns/netof a container without proper restrictions.Mitigations in place:
no-new-privileges:true,NET_ADMINnever granted,NET_RAWexplicitly dropped. The practical risk is low on patched kernels but represents a non-minimal attack surface.In non-chroot mode,
cap_sys_chrootandcap_sys_adminare present at runtime sincecapsh --drop=is a no-op with an empty list. The agent's command inherits these capabilities. Whileno-new-privileges:truelimits further escalation, running withSYS_ADMINallows mounting operations.Domain Validation Assessment
STRONG — Comprehensive input validation with defense-in-depth sanitization.
validateDomainOrPattern()(src/domain-patterns.ts) enforces:DOMAIN_DANGEROUS_CHARS:/[\s\0"';#\]/` (including backslash)*,*.*,*.*.*(too many wildcards)[a-zA-Z0-9.-]*character class (not.*)isDomainMatchedByPattern()assertSafeForSquidConfig()re-validates before Squid config interpolation (src/squid-config.ts:64):subdomains: falsein YAML rulesets has no effectSquid config always adds subdomain matching for plain domains (
src/squid-config.ts:73-79). A user who creates a ruleset withsubdomains: falseexpecting exact-match-only behavior will unknowingly allow all subdomains. This is documented in code comments but the API contract is misleading.Example: A ruleset entry
{ domain: "internal.example.com", subdomains: false }still allowsevil.internal.example.comin Squid ACL.Input Validation Assessment
STRONG — User command passed via Docker CMD array (no shell interpolation).
The user command goes through
src/cli.ts → src/docker-manager.tsas a Docker CMD array, not shell expansion.escapeShellArg()(src/cli.ts:938-951) properly single-quotes arguments.AWF_HOST_PATHinterpolated unquoted into shell heredocCommand 4: subdomains field no-op
✅ Zero known dependency vulnerabilities.
✅ Recommendations
🔴 Critical
None found.
🟠 High
None found.
🟡 Medium
M1 — Block ICMP at container-level iptables (Finding NET-1)
Add an explicit ICMP DROP rule to
containers/agent/setup-iptables.shbefore the final TCP/UDP drops:# After the existing DNS allow rules, before TCP/UDP DROP: iptables -A OUTPUT -p icmp -j DROPThis closes the ICMP covert channel (ptunnel-ng) at the container level as a defense-in-depth measure, rather than relying solely on the host FW_WRAPPER chain.
M2 — Remove or restrict
unshareandsetnsfrom seccomp ALLOW (Finding SEC-1)In
containers/agent/seccomp-profile.json, moveunshareandsetnsto the SCMP_ACT_ERRNO group (Group 3), or add conditions (e.g., only allowunsharewith non-CLONE_NEWUSERflags via seccomp arg filtering):{ "names": ["unshare", "setns"], "action": "SCMP_ACT_ERRNO", "comment": "Block namespace creation/entry - not needed for development tools" }Verify this doesn't break JVM, .NET CLR, or container runtimes that use
unsharefor sandboxing their own processes.M3 — Fix
subdomains: falseYAML ruleset field to actually work (Finding DOMAIN-1)In
src/rules.ts, implement the intended behavior:And update
src/squid-config.tsto generatedstdomain exact.com(without leading dot) for exact-match entries. Until fixed, add a warning in the CLI when a ruleset containssubdomains: false.🔵 Low
L1 — Quote
AWF_HOST_PATHinterpolation in heredoc (Finding INJ-1)In
containers/agent/entrypoint.sh, use a quoted heredoc for the PATH line to prevent variable expansion:Alternatively, validate
AWF_HOST_PATHinsrc/docker-manager.tsto reject values containing shell metacharacters.L2 — Drop
SYS_ADMINin non-chroot mode too (Finding SEC-2)Even in non-chroot mode,
SYS_ADMINcapability is not needed after container initialization. Consider removing it fromcap_addwhen chroot is not requested, or explicitly dropping it in the non-chroot path:This reduces the blast radius if another container escape mechanism is found.
📈 Security Metrics
🏅 Notable Security Strengths
NET_ADMINnever granted to agent — iptables init container pattern is elegant and correct/proc/self/environexposureptraceexplicitly ERRNO'd in both seccomp (Group 2) andcap_drop(SYS_PTRACE) — double-blocked/dev/nullbind mount — DinD requires explicit opt-inno-new-privileges:trueprevents setuid/setcap escalationassertSafeForSquidConfig()validates all interpolated valuesBeta Was this translation helpful? Give feedback.
All reactions