Found by the review of #339 (#339 (comment)). Out of that PR's scope, since it changes the list rather than documents it.
The SSRF guard's lists in internal/delivery/ssrf.go (blockedNetworks and alwaysBlockedNetworks) do not cover the IPv6 unspecified address ::. On Linux a connection to [::] reaches the host's own loopback, so a delivery target such as http://[::]:8080/ passes the guard with no allowlist set. IPv6 multicast (ff00::/8) and documentation space (2001:db8::/32) are not listed either. The IPv4 unspecified address is worth checking at the same time.
Definition of done
::/128 is refused wherever 0.0.0.0 is today, or in alwaysBlockedNetworks if it can reach loopback, because the allowlist must never reopen loopback.
ff00::/8 and 2001:db8::/32 are refused by default.
Each entry has a one-line comment naming what it is.
Tests:
each address is refused at target creation and at delivery, with no allowlist set;
each fails when its entry is removed.
The README's blocklist description matches the list.
Model: opus-5-5
Found by the review of https://git.eeqj.de/sneak/webhooker/pulls/339 (https://git.eeqj.de/sneak/webhooker/pulls/339#issuecomment-106662). Out of that PR's scope, since it changes the list rather than documents it.
The SSRF guard's lists in `internal/delivery/ssrf.go` (`blockedNetworks` and `alwaysBlockedNetworks`) do not cover the IPv6 unspecified address `::`. On Linux a connection to `[::]` reaches the host's own loopback, so a delivery target such as `http://[::]:8080/` passes the guard with no allowlist set. IPv6 multicast (`ff00::/8`) and documentation space (`2001:db8::/32`) are not listed either. The IPv4 unspecified address is worth checking at the same time.
## Definition of done
- `::/128` is refused wherever `0.0.0.0` is today, or in `alwaysBlockedNetworks` if it can reach loopback, because the allowlist must never reopen loopback.
- `ff00::/8` and `2001:db8::/32` are refused by default.
- Each entry has a one-line comment naming what it is.
- Tests:
- each address is refused at target creation and at delivery, with no allowlist set;
- each fails when its entry is removed.
- The README's blocklist description matches the list.
Model: opus-5-5
clawbot
self-assigned this 2026-09-29 11:10:38 +02:00
Plan. The issue body is the brief; #407 has since split the default blocklist into its private-and-reserved list (blockedNetworks), its public list (blockedPublicNetworks) and the unconditional list (alwaysBlockedNetworks).
::/128 goes where the issue says: in alwaysBlockedNetworks if, as on Linux, a connection to it reaches the host's loopback, so the allowlist can never reopen it; 0.0.0.0 is checked the same way and moved there if it is not already refused unconditionally.
ff00::/8 (IPv6 multicast) and 2001:db8::/32 (IPv6 documentation) go in blockedNetworks as reserved space, each with a one-line comment.
407's pinning test pins the new entries in their lists; new tests refuse each address at target creation and at delivery, and fail when its entry is removed.
The README's blocklist description (from #244) and the rules above each list are updated to match.
Model: opus-5-5
Plan. The issue body is the brief; https://git.eeqj.de/sneak/webhooker/pulls/407 has since split the default blocklist into its private-and-reserved list (`blockedNetworks`), its public list (`blockedPublicNetworks`) and the unconditional list (`alwaysBlockedNetworks`).
- `::/128` goes where the issue says: in `alwaysBlockedNetworks` if, as on Linux, a connection to it reaches the host's loopback, so the allowlist can never reopen it; `0.0.0.0` is checked the same way and moved there if it is not already refused unconditionally.
- `ff00::/8` (IPv6 multicast) and `2001:db8::/32` (IPv6 documentation) go in `blockedNetworks` as reserved space, each with a one-line comment.
- 407's pinning test pins the new entries in their lists; new tests refuse each address at target creation and at delivery, and fail when its entry is removed.
- The README's blocklist description (from https://git.eeqj.de/sneak/webhooker/issues/244) and the rules above each list are updated to match.
Model: opus-5-5
On this host a connection to [::] reaches a listener on ::1, and one to 0.0.0.0 reaches a listener on 127.0.0.1; other 0.0.0.0/8 addresses reach nothing local. So 0.0.0.0/32 and ::/128 are now in alwaysBlockedNetworks, where no allowlist opens them, and ::/128 also joins the default blocklist beside 0.0.0.0/8. ff00::/8 and 2001:db8::/32 are refused by default and can be reopened. Every default blocklist entry has a one-line comment, the pinning tests cover each list's new entries, a new test refuses each address at target creation and at delivery, and the README and the rules above each list are updated.
Judgement call: the unspecified addresses disclose nothing, so they fail the second half of the unconditional list's inclusion criterion; the rule above the list now states the exception and why.
Judgement call: comments were added to every existing default blocklist entry, not only the new ones.
Model: opus-5-5
Done in https://git.eeqj.de/sneak/webhooker/pulls/422.
On this host a connection to `[::]` reaches a listener on `::1`, and one to `0.0.0.0` reaches a listener on `127.0.0.1`; other `0.0.0.0/8` addresses reach nothing local. So `0.0.0.0/32` and `::/128` are now in `alwaysBlockedNetworks`, where no allowlist opens them, and `::/128` also joins the default blocklist beside `0.0.0.0/8`. `ff00::/8` and `2001:db8::/32` are refused by default and can be reopened. Every default blocklist entry has a one-line comment, the pinning tests cover each list's new entries, a new test refuses each address at target creation and at delivery, and the README and the rules above each list are updated.
- Judgement call: the unspecified addresses disclose nothing, so they fail the second half of the unconditional list's inclusion criterion; the rule above the list now states the exception and why.
- Judgement call: comments were added to every existing default blocklist entry, not only the new ones.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found by the review of #339 (#339 (comment)). Out of that PR's scope, since it changes the list rather than documents it.
The SSRF guard's lists in
internal/delivery/ssrf.go(blockedNetworksandalwaysBlockedNetworks) do not cover the IPv6 unspecified address::. On Linux a connection to[::]reaches the host's own loopback, so a delivery target such ashttp://[::]:8080/passes the guard with no allowlist set. IPv6 multicast (ff00::/8) and documentation space (2001:db8::/32) are not listed either. The IPv4 unspecified address is worth checking at the same time.Definition of done
::/128is refused wherever0.0.0.0is today, or inalwaysBlockedNetworksif it can reach loopback, because the allowlist must never reopen loopback.ff00::/8and2001:db8::/32are refused by default.Model: opus-5-5
Plan. The issue body is the brief; #407 has since split the default blocklist into its private-and-reserved list (
blockedNetworks), its public list (blockedPublicNetworks) and the unconditional list (alwaysBlockedNetworks).::/128goes where the issue says: inalwaysBlockedNetworksif, as on Linux, a connection to it reaches the host's loopback, so the allowlist can never reopen it;0.0.0.0is checked the same way and moved there if it is not already refused unconditionally.ff00::/8(IPv6 multicast) and2001:db8::/32(IPv6 documentation) go inblockedNetworksas reserved space, each with a one-line comment.Model: opus-5-5
Done in #422.
On this host a connection to
[::]reaches a listener on::1, and one to0.0.0.0reaches a listener on127.0.0.1; other0.0.0.0/8addresses reach nothing local. So0.0.0.0/32and::/128are now inalwaysBlockedNetworks, where no allowlist opens them, and::/128also joins the default blocklist beside0.0.0.0/8.ff00::/8and2001:db8::/32are refused by default and can be reopened. Every default blocklist entry has a one-line comment, the pinning tests cover each list's new entries, a new test refuses each address at target creation and at delivery, and the README and the rules above each list are updated.Model: opus-5-5