google-gemini / google-gemini/gemini-cli
security: web_fetch SSRF guard bypassed by DNS names resolving to private IPs
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
## Summary
`WebFetchTool.isBlockedHost()` blocks only IP literals (`localhost`, `127.0.0.1`)
but passes any DNS hostname to the synchronous `isPrivateIp()`, which returns `false`
for non-IP strings without resolving DNS.
This allows bypass via:
- `http://127.0.0.1.nip.io/` → resolves to 127.0.0.1 ✅ bypassed
- `http://169.254.169.254.nip.io/` → cloud metadata ✅ bypassed
- Any attacker-controlled DNS resolving to RFC-1918
## Impact
LLM agent via indirect prompt injection can reach loopback services and
cloud metadata endpoints (GCP/AWS/Azure IAM credentials).
## Proposed Fix
Replace synchronous `isPrivateIp()` with async `isPrivateIpAsync()` (already
in `utils/fetch.ts` but unused here) + IP pinning to prevent DNS rebinding.
A complete patch with tests is ready: #27744
Contributor guide
Research direction
Start at WebFetchTool.isBlockedHost() and compare its use of isPrivateIp() with isPrivateIpAsync() in utils/fetch.ts; review the complete patch and tests referenced in #27744. Verify that DNS names resolving to private addresses and DNS rebinding cannot bypass the guard, then run the relevant security tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100