Skip to content

fix: strengthen fetch_url IP validation - #1126

Open
awhite0030 wants to merge 1 commit into
Nano-Collective:mainfrom
awhite0030:fix/fetch-url-ip-validation-16788928792476340289
Open

fix: strengthen fetch_url IP validation#1126
awhite0030 wants to merge 1 commit into
Nano-Collective:mainfrom
awhite0030:fix/fetch-url-ip-validation-16788928792476340289

Conversation

@awhite0030

Copy link
Copy Markdown
Contributor

Description

Brief description of what this PR does

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Changeset

  • Added a changeset (pnpm changeset) describing this change for the changelog

Docs-only or internal chores need no changeset (or run pnpm changeset --empty to note that intentionally).

Testing

Automated Tests

  • New features include passing tests in .spec.ts/tsx files
  • All existing tests pass (pnpm test:all completes successfully)
  • Tests cover both success and error scenarios

Manual Testing

  • Tested with Ollama
  • Tested with OpenRouter
  • Tested with OpenAI-compatible API
  • Tested MCP integration (if applicable)

Checklist

  • If this was for an open issue, I was assigned to it
  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (if needed)
  • No breaking changes (or clearly documented)
  • Appropriate logging added using structured logging (see CONTRIBUTING.md)

Root cause: The validation for fetch_url's loopback and internal network check was relying on strict string matching for exact values (e.g., 127.0.0.1, localhost) rather than correctly analyzing the normalized hostname as an IPv4/IPv6 block. This allowed large portions of the loopback block (e.g., 127.0.0.2), cloud metadata targets, and IPv4-mapped IPv6 equivalents to bypass validation. Furthermore, validation was not performed at execution, meaning if it was skipped or bypassed, the IP was fetched regardless, while correctly resolving public domains like 10.example.com were falsely flagged.

Fix: Replaced the ad-hoc string comparisons with a unified validateUrlInternal helper used in both the executor and validator. It strips trailing dots and leverages net.isIPv4 and net.isIPv6 to correctly parse dotted quads and bracketed IP ranges. It now explicitly matches the entire 127.0.0.0/8, 169.254.0.0/16, 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 networks, as well as equivalent IPv6 and IPv4-mapped formats. Since it restricts the range match to only valid IP addresses, it now correctly allows domains like 10.example.com.

Validation:

corepack enable >/dev/null 2>&1 || true
pnpm install --frozen-lockfile
pnpm run build
pnpm test:format
pnpm test:lint
pnpm test:types
pnpm test:knip
pnpm test:ava source/tools/fetch-url.spec.tsx

All commands ran and passed without errors, demonstrating validation rejects SSRF patterns and successfully compiles.

Fixes #1088

Fixes #1088

This commit unifies IP validation logic in fetch-url by extracting it into a
`validateUrlInternal` function, which now properly inspects parsed `net.isIPv4`
and `net.isIPv6` properties instead of strictly matching string prefixes. This
closes vulnerabilities allowing loopback range bypasses (e.g. 127.0.0.2), IPv4-mapped
IPv6 loopbacks, cloud metadata IP bypasses, and FQDNs with trailing dots. It also
fixes the bug where valid domains starting with "10." were being falsely blocked.
@github-actions github-actions Bot added the area:tools Tool implementations and tool-calling label Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tools Tool implementations and tool-calling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] fetch_url allows loopback aliases and cloud metadata hosts

1 participant