Fix a security bug: block SSRF in WebFetchTool by validating resolved IP addresses#1012
Fix a security bug: block SSRF in WebFetchTool by validating resolved IP addresses#1012chengpeng-wang wants to merge 5 commits intosipeed:mainfrom
Conversation
Add a function to block requests to private/internal addresses. SSRF resolved.
|
@chengpeng-wang please fix Linter and tests bug |
|
Five tests in
All five used SolutionReplaced Changes
|
Code reviewFound 4 issues:
The Lines 586 to 604 in 094c6cf
The PR adds Lines 596 to 600 in 094c6cf
The PR adds a new security-critical function Lines 586 to 604 in 094c6cf
When DNS resolution fails (e.g., temporary network issues), the function returns an error and blocks the request. This means temporary DNS issues would prevent users from accessing any website, even public ones. Consider differentiating between "DNS failed" vs "resolved to private IP". Lines 589 to 591 in 094c6cf 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
Issue 1 — TOCTOU / DNS Rebinding AttackRoot cause: Fix: Added Issue 2 — Tests Failing Due to LocalhostAlready resolved in a prior change via Issue 3 — Missing Unit Tests for
|
| Situation | Error message |
|---|---|
| DNS lookup failed | DNS resolution failed for host "example.com": <underlying error> |
| IP is private/internal | requests to private/internal addresses are not allowed |
Callers and users can now distinguish a transient network problem from a deliberate SSRF block.
|
@yinwm I have signed the CLA. Could you please review the change and approve the workflow to run the test? |
|
@chengpeng-wang Hi! This PR has had no activity for over 2 weeks, so I'm closing it for now to keep things organized. Feel free to reopen anytime if you'd like to continue. |
Summary
WebFetchTool.Executeallowed fetching arbitrary URLs without validating the resolved IP address. This made it trivially possible to reach localhost services, private network hosts, and cloud metadata endpoints — a classic Server-Side Request Forgery (SSRF) vulnerability.Problem
The original code only checked:
httporhttpsBut it never checked what IP the hostname actually resolved to, meaning requests like the following were silently allowed:
For users running picoclaw locally, this is especially relevant in a Prompt Injection + SSRF combined attack scenario:
web_fetchagainst internal addressesFix
Added
blockPrivateTarget()which runs before the HTTP request is made:This blocks:
127.0.0.0/8— loopback10.0.0.0/8,172.16.0.0/12,192.168.0.0/16— private networks169.254.0.0/16— link-local / cloud metadata::1— IPv6 loopbackfc00::/7,fe80::/10— IPv6 private and link-local0.0.0.0)Security Impact