feat: blocked_networks config and extended SSRF ranges (closes #67)
check / check (push) Failing after 1s
check / check (push) Failing after 1s
Adds the blocked_networks config key: a list of CIDRs, parsed with net/netip, that is added to the built-in list of address ranges the fetcher refuses to contact and can never remove an entry from it. An invalid CIDR aborts startup naming the key and the value. The built-in list gains CGNAT 100.64.0.0/10, IETF protocol assignments 192.0.0.0/24, benchmark 198.18.0.0/15 and NAT64 64:ff9b::/96. Resolved addresses are unmapped before matching, so IPv4-mapped IPv6 forms are caught too. Enforcement stays in the dial-time re-resolution, which is what closes the DNS rebinding window. What a reader would trip over: 192.0.0.0/24 is now blocked but TEST-NET-1 (192.0.2.0/24), which the Fetch tests use as a public upstream, is a different range and stays dialable. The package-level dialer enforces the built-in ranges only; operator entries are applied by the fetcher. Disclosure: one nolint:gochecknoglobals on the immutable built-in prefix list. Model: opus-4-8 (implementation, review); fable-5-1 (landing message)
This commit was merged in pull request #124.
This commit is contained in:
@@ -122,6 +122,10 @@ Configured via YAML file (`--config`). Key settings:
|
||||
|
||||
- `access_control_allow_origin` — CORS origin
|
||||
- `allowlist_hosts` — list of allowed upstream hosts
|
||||
- `blocked_networks` — list of CIDR ranges to refuse for SSRF protection,
|
||||
added to the always-enforced built-in ranges (loopback, private,
|
||||
link-local, CGNAT, benchmark, NAT64, and the like); an invalid CIDR
|
||||
aborts startup
|
||||
- `upstream_fetch_timeout` — timeout for origin requests
|
||||
- `upstream_max_response_size` — max origin response size
|
||||
- `downstream_timeout` — client response timeout
|
||||
|
||||
Reference in New Issue
Block a user