fix(web-fetch): block private/IMDS addresses to prevent SSRF#504
Conversation
Add AllowPrivateNetworks and AdditionalBlockedHosts to WebFetchConfig. AssertNotPrivateOrImds checks loopback, link-local/IMDS, RFC-1918, CGN, and known cloud metadata hostnames before every fetch. AllowPrivateNetworks=true bypasses the guard for self-hosted LAN use. Converted SecurityGap tests to enforcement tests; 71/71 pass. Closes #503
sytone
left a comment
There was a problem hiding this comment.
Farnsworth Review — PR #504
CI: ✅ All checks passing (build-and-test, CodeQL, CodePatterns, TruffleHog)
Merge conflicts: ✅ Clean (MERGEABLE)
Conventional commit title: ✅ fix(web-fetch): block private/IMDS addresses to prevent SSRF
Test coverage:
- ✅ Happy path: public URLs still allowed
- ✅ Sad paths: loopback, IMDS (169.254.169.254), RFC-1918, GCP/Azure hostnames all blocked
- ✅ Opt-out path:
AllowPrivateNetworks=truebypasses block - ✅
AdditionalBlockedHostscustom blocklist - 71/71 WebTools tests pass
Spec completeness vs #503: Fully satisfies all acceptance criteria — AllowPrivateNetworks, AdditionalBlockedHosts, IPv6 ULA, CGN, IMDS hostname variants all covered.
Notes: Minimal, focused change. No regressions. DNS-name localhost blocked explicitly — good. Consider future improvement: DNS resolution check (hostname that resolves to 127.x) but that's not required by the issue.
LGTM. Ready to merge.
|
Closing as part of a planned hard-reset of the in-flight branch set so the new domain-model refactor can land on a clean trunk. Audit verdict: security Rationale: SECURITY FIX. The underlying SSRF vulnerability remains in main after closure - must be re-applied as a fresh PR. See #503. The new plan (in session state) reshapes core types: Citizen (User+Agent union), Vogen-generated value objects, ThreadId removed in favour of composite ChannelAddress, mark-not-delete compaction, centralised If this work is still wanted, refile as a new issue/PR against the post-refactor contracts. |
Closes #503
Changes
WebFetchConfig(new fields)AllowPrivateNetworks(defaultfalse) — when false, private/loopback/IMDS ranges are blockedAdditionalBlockedHosts— exact hostname blocklist (case-insensitive)WebFetchTool(SSRF guard)AssertNotPrivateOrImdscalled inPrepareArgumentsAsyncafter scheme validation169.254.169.254,metadata.google.internal,metadata.azure.internal,fd00:ec2::254localhost(DNS name) also blockedAllowPrivateNetworks=truebypasses all IP range checks (for self-hosted LAN deployments)Tests
SecurityGaptests converted to enforcement tests (7 URL variants)AllowPrivateNetworks=trueopt-out,AdditionalBlockedHosts, IMDS hostnameSecurity Impact
Blocks SSRF attacks targeting cloud IMDS endpoints (
169.254.169.254/latest/meta-data/iam/...,metadata.google.internal/computeMetadata/v1/...) and internal network services from agent tool calls.