fix(security): C6 — extend SSRF block to RFC-1918 + IMDS ranges - #107
fix(security): C6 — extend SSRF block to RFC-1918 + IMDS ranges#107HongmingWang-Rabbit wants to merge 1 commit into
Conversation
validateAgentURL previously blocked only 169.254.0.0/16 (link-local / cloud metadata). This patch extends the blocked set to cover all private and loopback ranges that can be used as SSRF vectors: 10.0.0.0/8 RFC-1918 class A 172.16.0.0/12 RFC-1918 class B (includes Docker bridge 172.17–31.x.x) 192.168.0.0/16 RFC-1918 class C ::1/128 IPv6 loopback fc00::/7 IPv6 unique-local (fd00::/8 sub-range included) CIDRs are pre-parsed into a package-level slice so net.ParseCIDR is not called on every request. Hostname-based URLs are resolved via DNS before the check; DNS failures are fail-open to avoid blocking legitimate registrations on transient outages. Test changes: - Three existing test cases that incorrectly asserted RFC-1918 addresses were valid (wantErr: false) are corrected to wantErr: true. - 15 new sub-cases cover range boundaries and all three new IPv6 ranges. - Test fixtures that used http://localhost: (which DNS-resolves to ::1 in this environment) are updated to http://127.0.0.1: so they remain valid until the sibling PR fix/c6-loopback-ssrf merges. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
This branch was created before PR #94 merged. Three issues that must be fixed:
Suggested path: git rebase origin/main
# Resolve conflicts by keeping main's localhost fixtures
# Add "127.0.0.0/8" to ssrfBlockedNets
# Update wantErr for 127.0.0.1 test case to trueThe DNS resolution + IPv6 + pre-parsed CIDR improvements are good and worth landing — they just need to build on top of the current main state. |
|
Superseded by #119 which takes the targeted approach: adds only the three IPv6 CIDRs (fe80::/10, ::1/128, fc00::/7) to the existing blockedRanges without removing the loopback and RFC-1918 IPv4 blocks that this PR's ssrfBlockedNets var omitted. |
Summary
validateAgentURL(introduced in PR fix(security): C6 — block loopback IP literals in /registry/register #94) to block all private IP ranges, not just link-local:10.0.0.0/8— RFC-1918 class A172.16.0.0/12— RFC-1918 class B (includes Docker bridge 172.17–31.x.x)192.168.0.0/16— RFC-1918 class C::1/128— IPv6 loopbackfc00::/7— IPv6 unique-local (coversfd00::/8sub-range)169.254.0.0/16(link-local / AWS IMDS) was already blocked; preserved.ssrfBlockedNetsslice — no per-requestParseCIDRcost.What changed
platform/internal/handlers/registry.gossrfBlockedNetsvar; rewrotevalidateAgentURLto iterate all blocked ranges + DNS resolveplatform/internal/handlers/registry_test.goplatform/internal/handlers/handlers_test.gohttp://localhost:fixture URLs tohttp://127.0.0.1:(DNS-safe for this environment)Relation to PR #94
validateAgentURL. Once fix(security): C6 — block loopback IP literals in /registry/register #94 lands, the127.0.0.1test case in this PR should be updated towantErr: trueand a loopback CIDR added tossrfBlockedNets.Test plan
CGO_ENABLED=0 go test ./...— all packages passTestValidateAgentURLall pass (3 RFC-1918 ranges × 3 boundary IPs each + 3 IPv6 + existing link-local + scheme/input tests)🤖 Generated with Claude Code