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:
@@ -25,10 +25,20 @@ The disk cache is now size-bounded with LRU eviction
|
||||
|
||||
# Next Step
|
||||
|
||||
P1: implement blocked networks configuration to extend SSRF protection
|
||||
P1: rate limit global concurrent upstream fetches to prevent resource
|
||||
exhaustion
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-09-21 blocked networks configuration extending SSRF protection: a
|
||||
`blocked_networks` config key taking a list of CIDRs (parsed with
|
||||
`net/netip`, an invalid entry aborts startup naming the key and value),
|
||||
added to the built-in blocklist rather than replacing it; the built-in
|
||||
ranges extended to 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`
|
||||
(IPv4-mapped forms covered); enforcement stays in the dial-time
|
||||
re-resolution so the DNS-rebinding window remains closed; documented in
|
||||
`README.md` and `config.example.yml`.
|
||||
- 2026-09-21 http.Server hardening (closes #92): added
|
||||
`HTTPReadHeaderTimeout` (10s, bounds the slowloris header dribble) and
|
||||
`HTTPIdleTimeout` (120s, bounds keep-alive reuse) alongside the
|
||||
@@ -130,8 +140,6 @@ P1: implement blocked networks configuration to extend SSRF protection
|
||||
|
||||
# Future Steps
|
||||
|
||||
- P1: rate limit global concurrent upstream fetches to prevent
|
||||
resource exhaustion
|
||||
- P1: strip EXIF and other metadata from processed images (privacy)
|
||||
- P2: security
|
||||
- referer blacklist
|
||||
|
||||
Reference in New Issue
Block a user