#116 · SSRF: DNS rebind hardening + Tailscale CGNAT block
Description
Context
packages/shared-utils/src/bot-utils/url-scraper.ts:178 validates URLs by checking the literal hostname string against an allowlist + isInternalHost check, then axios.get(url) re-resolves DNS independently. An attacker domain returning 203.0.113.5 on the first lookup and 127.0.0.1 on the second bypasses the check (DNS rebinding).
Also: isInternalHost blocks 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, but NOT 100.64.0.0/10 (CGNAT) — relevant because the bot itself runs on Tailscale at 100.87.20.88, so a rebound DNS could hit Tailscale-internal services (Authentik, GitLab, Outline, MinIO admin).
Acceptance criteria
- [ ] Resolve DNS once before the fetch; validate the resolved IP against block ranges
- [ ] Pin the fetch to that IP via
axioscustomhttpAgentwithlookupreturning the validated IP, OR fetch with manually constructedhttp.requestto the IP and the originalHostheader - [ ] Add
100.64.0.0/10(RFC 6598 CGNAT, includes Tailscale) to the blocklist - [ ] Add IPv6 link-local (
fe80::/10), IPv6 ULA (fc00::/7),::1/128 - [ ] Block AWS/GCP/Azure metadata IPs:
169.254.169.254,fd00:ec2::254 - [ ] Cap redirects at 3 and revalidate the IP after each redirect (axios's default follows redirects without re-checking)
- [ ] Test: confirm a domain that returns 8.8.8.8 then 127.0.0.1 across two lookups gets blocked
Technical hints
- The
dns.lookup()call gives you the IP; pass it viaagent: new http.Agent({lookup: (host, opts, cb) => cb(null, validatedIp, 4)}) - Tailscale CGNAT: 100.64.0.0/10 covers 100.64.0.0 to 100.127.255.255
- Look at how the Q&A worker handles SSRF for reference (if it does)
- Add a unit test for the IP-validation function so future config changes don't regress
--- *M-tier (100 pts + 40 merge_pr = 140). Touches a shared package — affects all bot URL-fetching paths.*
Relevant files
No relevant files linked yet.
Hints
No hints yet.
Activity
- +100 Günther Van der Eecken earned M bounty Jun 14
Comments
Sign in to join the discussion.
No comments yet. Be the first to weigh in.