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:
@@ -22,6 +22,15 @@ allowlist_hosts:
|
||||
- github.com
|
||||
- user-images.githubusercontent.com
|
||||
|
||||
# Additional CIDR ranges to refuse when fetching upstream, extending the
|
||||
# SSRF protection. These are added to the always-enforced built-in ranges
|
||||
# (loopback, RFC 1918 private, link-local, CGNAT, benchmark, NAT64, and
|
||||
# similar), never replacing them. Each entry must be a valid CIDR in IPv4
|
||||
# or IPv6 form; an invalid entry aborts startup.
|
||||
# blocked_networks:
|
||||
# - 100.64.0.0/10
|
||||
# - 2001:db8::/32
|
||||
|
||||
# Allow HTTP upstream (only for testing, always use HTTPS in production)
|
||||
allow_http: false
|
||||
|
||||
|
||||
Reference in New Issue
Block a user