Skip to content

[Feature]: web_fetch: pass ssrfPolicy from config to fetchWithSsrFGuard (fix fake-IP/proxy environments) #28271

@hyj223

Description

@hyj223

Summary

web_fetch is completely broken in fake-IP proxy environments (Surge Enhanced Mode, Clash fake-ip, etc.) because the SSRF guard blocks RFC 2544 benchmark range (198.18.0.0/15) addresses used by these proxies for DNS interception.

Root Cause

In src/agents/tools/web-guarded-fetch.ts, fetchWithWebToolsNetworkGuard() calls fetchWithSsrFGuard() without passing any policy:

export async function fetchWithWebToolsNetworkGuard(
  params: WebToolGuardedFetchOptions,
): Promise<GuardedFetchResult> {
  const { timeoutSeconds, ...rest } = params;
  return fetchWithSsrFGuard({
    ...rest,
    timeoutMs: resolveTimeoutMs({ timeoutMs: rest.timeoutMs, timeoutSeconds }),
    proxy: "env",
    // ← no policy passed!
  });
}

Meanwhile, the file already defines WEB_TOOLS_TRUSTED_NETWORK_SSRF_POLICY but never uses it.

In src/agents/tools/web-fetch.ts, runWebFetch() calls fetchWithWebToolsNetworkGuard() without any policy either.

The SSRF guard code in src/shared/net/ip.ts already supports allowRfc2544BenchmarkRange opt-out, but there is no config path to reach it from web_fetch.

In contrast, the browser tool has browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true by default — creating an inconsistency.

Proposed Fix

Three small changes:

  1. src/config/types.tools.ts — Add ssrfPolicy to the fetch config type:
fetch?: {
  // ... existing fields ...
  /** SSRF policy for web fetch requests. */
  ssrfPolicy?: {
    /** Allow private/internal network addresses (default: false). */
    dangerouslyAllowPrivateNetwork?: boolean;
    /** Allow RFC 2544 benchmark range 198.18.0.0/15 (default: false). Needed for fake-IP proxy environments. */
    allowRfc2544BenchmarkRange?: boolean;
  };
};
  1. src/agents/tools/web-fetch.ts — Read ssrfPolicy from config and pass it through WebFetchRuntimeParams to fetchWithWebToolsNetworkGuard.

  2. src/agents/tools/web-guarded-fetch.ts — Accept and forward policy to fetchWithSsrFGuard.

Config Example

{
  tools: {
    web: {
      fetch: {
        ssrfPolicy: {
          allowRfc2544BenchmarkRange: true  // Allow 198.18.0.0/15 for Surge/Clash fake-IP
        }
      }
    }
  }
}

Why This Is Safe

  • allowRfc2544BenchmarkRange only unblocks 198.18.0.0/15 — a non-routable range never used on the public internet
  • All other private/internal/special-use ranges remain blocked
  • dangerouslyAllowPrivateNetwork is opt-in (default false), unlike browser tool which defaults to true
  • The SSRF guard code already implements the check — this just adds a config path

Who Is Affected

Every user running Surge (macOS/iOS), Clash, Shadowrocket, Quantumult X, Stash, or similar tools in fake-IP/TUN mode.

Related Issues

Environment

  • macOS (Darwin, arm64)
  • Proxy with fake-IP mode (DNS → 198.18.x.x for all domains)
  • OpenClaw latest stable

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