Skip to content

fix(webfetch): block loopback/private/link-local/metadata hosts (SSRF guard)#4

Open
NubsCarson wants to merge 1 commit into
devfrom
nubs/webfetch-ssrf-guard
Open

fix(webfetch): block loopback/private/link-local/metadata hosts (SSRF guard)#4
NubsCarson wants to merge 1 commit into
devfrom
nubs/webfetch-ssrf-guard

Conversation

@NubsCarson

@NubsCarson NubsCarson commented May 31, 2026

Copy link
Copy Markdown
Member

Issue for this PR

Closes # — N/A (issues are disabled on this repository, so there's no issue to link; happy to file one elsewhere if a maintainer prefers).

Type of change

  • Bug fix

What does this PR do?

webfetch only checks the URL scheme (http/https) — there's no host filtering, and redirects are followed by default. Because webfetch can be driven by autonomous agents (and is reachable via prompt injection), a bare GET can be aimed at internal services: loopback, private LAN ranges, or cloud metadata at 169.254.169.254. The response body is handed back to the model, so it's a usable SSRF / internal-data-exfil primitive.

This adds isBlockedFetchHost() and checks the resolved URL hostname before fetching, rejecting: localhost/*.local/*.internal, IPv4 loopback 127/8 + 0.x, private 10/8/172.16-31/192.168/16, link-local + metadata 169.254/16, and IPv6 ::1/::/ULA fc00::/7/link-local fe80::/10. Public hosts are unaffected. It's a string/range guard on the URL host (the common high-value targets); it intentionally doesn't attempt full DNS-rebinding-time protection.

How did you verify your code works?

Unit-tested the host classifier across public hosts (allowed, incl. 8.8.8.8 and a fc-… domain) and internal hosts (blocked: localhost, 127/10/192.168/172.16, 169.254.169.254, [::1]). Ran it live in a downstream deployment: public crypto/FX/weather fetches still work with zero false-positives, and internal targets are refused.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

… guard)

webfetch can be driven by autonomous agents, so a bare GET must not be usable
to reach internal services. Reject loopback (127.0.0.0/8, ::1), private
(10/8, 172.16/12, 192.168/16), link-local + cloud metadata (169.254/16,
169.254.169.254), IPv6 ULA/link-local, and *.local/*.internal/localhost hosts
before fetching. Public hosts are unaffected.
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aee9db84-e35d-4d8e-a6be-0db1345e9f14

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nubs/webfetch-ssrf-guard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 31, 2026

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • No issue referenced. Please add Closes #<number> linking to the relevant issue.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

@NubsCarson

Copy link
Copy Markdown
Member Author

Reopened. Note: this repo has Issues disabled, so the pr-standards bot's "link an issue" requirement cannot be satisfied here — requesting a manual maintainer review. The change is a defensive SSRF guard (blocks loopback/private/link-local/cloud-metadata hosts before webfetch's ctx.ask), unit-verified, no behavior change for public hosts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant