Skip to content

fix(web-fetch): block private/IMDS addresses to prevent SSRF#504

Closed
sytone wants to merge 1 commit into
mainfrom
fix/webfetch-ssrf
Closed

fix(web-fetch): block private/IMDS addresses to prevent SSRF#504
sytone wants to merge 1 commit into
mainfrom
fix/webfetch-ssrf

Conversation

@sytone
Copy link
Copy Markdown
Owner

@sytone sytone commented May 22, 2026

Closes #503

Changes

WebFetchConfig (new fields)

  • AllowPrivateNetworks (default false) — when false, private/loopback/IMDS ranges are blocked
  • AdditionalBlockedHosts — exact hostname blocklist (case-insensitive)

WebFetchTool (SSRF guard)

  • AssertNotPrivateOrImds called in PrepareArgumentsAsync after scheme validation
  • Blocks: loopback (127/8, ::1), link-local/IMDS (169.254/16, fe80::/10), RFC-1918 (10/8, 172.16/12, 192.168/16), CGN (100.64/10), IPv6 ULA (fc00::/7)
  • Named IMDS hostnames: 169.254.169.254, metadata.google.internal, metadata.azure.internal, fd00:ec2::254
  • localhost (DNS name) also blocked
  • AllowPrivateNetworks=true bypasses all IP range checks (for self-hosted LAN deployments)

Tests

  • 4 SecurityGap tests converted to enforcement tests (7 URL variants)
  • 3 new tests: AllowPrivateNetworks=true opt-out, AdditionalBlockedHosts, IMDS hostname
  • 71/71 pass

Security 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.

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
Copy link
Copy Markdown
Owner Author

@sytone sytone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=true bypasses block
  • AdditionalBlockedHosts custom 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.

@sytone
Copy link
Copy Markdown
Owner Author

sytone commented May 22, 2026

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 SessionContextProjector, single-path routing. Many in-flight branches touch contracts that are about to change — rebasing later would be more work than rebuilding on the new shape.

If this work is still wanted, refile as a new issue/PR against the post-refactor contracts.

@sytone sytone closed this May 22, 2026
@sytone sytone deleted the fix/webfetch-ssrf branch May 22, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] WebFetchTool allows SSRF -- no block on private/IMDS addresses

1 participant