Skip to content

web_fetch SSRF guard blocks Clash/Surge TUN fake-ip range (198.18.0.0/15) #48080

@xiafy

Description

@xiafy

Problem

When running OpenClaw on a host with Clash Pro (or Surge) in TUN/enhanced mode, all DNS resolutions return fake-ip addresses in the 198.18.0.0/15 range (RFC 2544 Benchmark). The web_fetch tool's SSRF guard blocks these as "private/internal/special-use IP address", making web_fetch completely unusable.

Error: Blocked: resolves to private/internal/special-use IP address

This affects all URLs — not just internal ones — because TUN mode hijacks DNS at the system level.

Environment

  • macOS (Apple Silicon)
  • ClashX Pro with TUN/enhanced mode enabled
  • utun interface bound to 198.18.0.1/16
  • All DNS queries return 198.18.x.x fake-ip addresses
  • Actual traffic is transparently forwarded to real public IPs via the proxy tunnel

Root Cause

web_fetch uses withStrictGuardedFetchMode() which performs DNS resolution → IP check before connecting. The resolved 198.18.x.x addresses are classified as RFC 2544 special-use and blocked.

The codebase already has allowRfc2544BenchmarkRange logic in resolveIpv4SpecialUseBlockOptions() (~line 6390 in model-selection), and browser.ssrfPolicy supports allowPrivateNetwork. However, web_fetch has no corresponding configuration — it's hardcoded to STRICT mode.

Proposed Solution

Add a configurable SSRF policy for web_fetch (and ideally all tool-level fetches), e.g.:

{
  "tools": {
    "ssrfPolicy": {
      "allowRfc2544BenchmarkRange": true
    }
  }
}

Or extend the existing browser.ssrfPolicy to a shared/global scope.

This is a narrow, safe change:

  • 198.18.0.0/15 is not used for real internal services
  • In TUN environments, these IPs are ephemeral mappings to public destinations
  • RFC 1918 private ranges (10.x, 172.16.x, 192.168.x) remain blocked
  • Does not weaken SSRF protection for actual internal network access

Impact

This likely affects a significant number of users in regions where proxy tools with TUN mode (Clash, Surge, Shadowrocket, Quantumult X) are commonly used.

Workaround

Currently using exec + curl as a substitute for web_fetch, which works because curl's traffic goes through the TUN tunnel normally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions