From c00c9a4dfd363d74d595c39acb51dbe1fe4aa1f0 Mon Sep 17 00:00:00 2001 From: xore Date: Sun, 6 Sep 2026 02:56:02 +0200 Subject: [PATCH] docs(sandbox): the forensic-egress allowlist is a destination filter, not read-only The allowlist was headed "Retrieval-only domains available to proxy-aware forensic samples", and the sandbox README described the same thing as a "retrieval proxy". Neither is enforced. Squid gates these names with `dstdomain` on CONNECT and then parses no HTTP inside the established tunnel, so it cannot distinguish a fetch from an upload, a clone from a push, or a raw read from a Gist/release/API write. Plain HTTP to port 80 against the same names is permitted too, since the allow rule is not CONNECT-restricted. The size caps do not close that either: `request_body_max_size` and `reply_body_max_size` act on message bodies squid parses, and a CONNECT tunnel has none, so tunneled traffic is unbounded in both directions. What actually remains is the access_log entry for the CONNECT -- host, port and byte counts, i.e. after-the-fact detection of volume, not prevention and not content. Says so, in both places, and notes that .github.io is shared multi-tenant hosting so an attacker-controlled .github.io is inside the list by construction. Documentation only -- no enforcement change, and this deliberately forecloses none of the directions in #3072 (TLS interception, splitting read-only from write-capable destinations). Squid ignores `#` lines in an ACL file, and nothing but squid reads this file. Refs #3072 --- docs/sandbox/README.md | 4 ++++ sandbox/forensic-egress-allowed-domains.txt | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/sandbox/README.md b/docs/sandbox/README.md index fee988f72..3ae9b0e20 100644 --- a/docs/sandbox/README.md +++ b/docs/sandbox/README.md @@ -189,6 +189,10 @@ the nftables chain accepts only DNS and the allowlisted proxy, nothing else. `forensic-egress-allowed-domains.txt`. DNS answers are real; both queries and responses are retained in the per-job capture. Direct guest connections, private destinations, arbitrary domains, and non-HTTP protocols stay blocked. + The allowlist bounds *where* a sample may connect, not what it may do there + (#3072): squid cannot see inside an established CONNECT tunnel, so every + allowlisted domain is reachable for upload as much as for download, and + tunneled volume shows up in the access log without being capped by it. For a new or existing foundation, the complete Wine-enabled installation can instead be run in the safe order with one command. It pauses an idle worker, diff --git a/sandbox/forensic-egress-allowed-domains.txt b/sandbox/forensic-egress-allowed-domains.txt index 44e479a93..0f911f35b 100644 --- a/sandbox/forensic-egress-allowed-domains.txt +++ b/sandbox/forensic-egress-allowed-domains.txt @@ -1,4 +1,23 @@ -# Retrieval-only domains available to proxy-aware forensic samples. +# Domains a proxy-aware forensic sample is permitted to reach. Retrieval of +# tooling and second-stage payloads during analysis is the operator intent +# behind every name here. +# +# It is intent, not enforcement (#3072). This is a *destination* allowlist: +# squid gates these names with `dstdomain` on CONNECT, and once the TLS +# tunnel is established it parses no HTTP inside it. It cannot tell a fetch +# from an upload, a `git clone` from a `git push`, or a raw read from a +# Gist/release/API write. Plain HTTP to port 80 against these names is +# permitted too. `request_body_max_size` / `reply_body_max_size` do not bound +# tunneled traffic -- they act on message bodies squid parses, and a CONNECT +# tunnel has none. What survives as mitigation is the access_log line for the +# CONNECT (host, port, transferred byte counts): after-the-fact detection of +# volume, not prevention, and not content. +# +# .github.io compounds this: GitHub Pages is shared multi-tenant hosting, so +# an attacker-controlled .github.io is inside this list by construction. +# +# Adding a name here grants a sample a bidirectional channel to it. Weigh it +# on that basis, not on what the domain is nominally used for. .github.com .githubusercontent.com .githubassets.com