Skip to content

fix(http): prevent DNS rebinding and SSRF in HTTP mode#30

Draft
reneaaron wants to merge 1 commit into
masterfrom
fix/http-dns-rebinding-ssrf
Draft

fix(http): prevent DNS rebinding and SSRF in HTTP mode#30
reneaaron wants to merge 1 commit into
masterfrom
fix/http-dns-rebinding-ssrf

Conversation

@reneaaron

Copy link
Copy Markdown
Member

Summary

HTTP mode (MODE=HTTP, incl. the hosted mcp.getalby.com) had two issues that chain into a private-network read:

  1. No Host/Origin validation on /mcp, /sse, /messages. A malicious web page can DNS-rebind its hostname to a loopback/private address and send browser-origin requests to a victim's local MCP listener.
  2. fetch_l402 fetched any caller-supplied URL and returned the body — an SSRF sink. "Auth" was only a nostr+walletconnect:// prefix check, which an attacker can satisfy with a fake connection secret (no real wallet needed, since a 200 response never triggers a payment).

Chained: rebind → reach local /mcp → fake nwc accepted → fetch_l402 reads e.g. http://127.0.0.1/internal/... → response returned to the attacker page.

Reported by Avishai Gonen (Pluto Security). Verified against bee4ffc (@getalby/mcp@1.1.1).

Changes

  • hostOriginGuard middleware (src/security.ts) on all HTTP endpoints. Loopback-only by default; extend via ALLOWED_HOSTS / ALLOWED_ORIGINS. Non-browser MCP clients (no Origin header) are unaffected.
  • assertPublicUrl SSRF guard in fetch_l402. Allows only http(s) URLs resolving exclusively to globally-routable addresses; blocks loopback, link-local (incl. 169.254.169.254), RFC1918, CGNAT and IPv6 local/ULA ranges, and unwraps IPv4-mapped IPv6. ALLOWED_FETCH_HOSTS is an opt-in escape hatch for local dev.
  • fly.toml: sets ALLOWED_HOSTS = 'mcp.getalby.com' so the hosted deployment keeps working.
  • README documents the three env vars.

Testing

  • yarn build passes.
  • Unit-checked assertPublicUrl: blocks 127.0.0.1, [::1], 169.254.169.254, 10/8, 192.168/16, ::ffff:127.0.0.1, file:; allows public hosts; honors ALLOWED_FETCH_HOSTS.
  • Live server: legit localhost Host passes the guard; rebinding Host: evil.com → 403; attacker Origin → 403.

Known limitations / follow-ups

  • DNS TOCTOU: assertPublicUrl resolves and validates, but fetchWithL402 re-resolves at fetch time — a rebind between the two could still slip through. The Host/Origin guard closes the primary browser vector; fully closing this needs pinning the validated IP at fetch time (would require changes in @getalby/lightning-tools).
  • Redirects: fetch_l402 follows redirects, so a public URL could 30x to a private one. Consider redirect: "manual" + re-validation.
  • Consider applying assertPublicUrl to request_invoice (lightning-address lookup) as well.
  • GitHub Private Vulnerability Reporting is not enabled on this repo — worth turning on.

HTTP mode exposed /mcp and /sse with no Host/Origin validation, and
fetch_l402 fetched any caller-supplied URL. Combined, a malicious web
page could DNS-rebind to a victim's local MCP listener and read private
HTTP resources via fetch_l402 (SSRF).

- Add hostOriginGuard middleware validating Host/Origin on all HTTP
  endpoints (loopback-only by default; ALLOWED_HOSTS/ALLOWED_ORIGINS to
  extend).
- Add assertPublicUrl SSRF guard to fetch_l402 that blocks loopback,
  link-local (incl. cloud metadata), RFC1918 and IPv6 local ranges;
  ALLOWED_FETCH_HOSTS opt-in for local development.
- Set ALLOWED_HOSTS on the Fly deployment so mcp.getalby.com keeps working.

Reported by Avishai Gonen (Pluto Security).
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d8923634-45b1-4ff0-bf31-44c3365b7bf8

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 fix/http-dns-rebinding-ssrf

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.

@rolznz

rolznz commented Jul 15, 2026

Copy link
Copy Markdown
Member

How is this exploitable in practice? the normal flow is that your agent can access a few alby MCP tools to communicate with your wallet.

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.

2 participants