Replies: 4 comments
|
源码侧全部核实(本地 0.1.2-alpha.1 = cd5ef81;alpha.2 仅版本号变动,web-fetch-http 源码与你的引用一致)。你的四条根因论断逐条都能对上,且这组文件里有一个你可能没注意到的现成注入点,让修复比想象中更顺。 核实结果(packages/web/web-fetch-http/):
增量发现(对修复评估重要):解析器注入点其实已经存在—— 三条建议的评估:
另:不建议把 198.18.0.0/15 直接当公网段放行(第三种隐式变体)——那等于对所有 DNS 答案开放该段,信任面是隐式的且无配置痕迹,不如显式配置可审计。 结论:方向 1 先行(外科手术式、守卫语义不变、有现成注入点),方向 2 作为配置面补充并注意收窄豁免范围,方向 3 立即补。PR 通道重开后这是可落地的候选;若先出插件形态(在 web-fetch-http 外注册包装 provider)也能验证思路,但配置口最终应在 in-tree。 |
|
感谢逐条核实,特别是 1. resolver 建议直接支持 DoH 形态(而非仅 UDP 指定服务器)。 真实受害部署里,OpenClash/Clash TUN 普遍劫持 UDP53: 2. allowDomains 收窄方案同意。 rebinding 反例成立——"仅豁免 198.18.0.0/15 等保留段、RFC1918/loopback/link-local 照拒"是正确形态。 |
|
Re-anchored against alpha.2 (
The fix direction satisfies #5202 and #4893 at once. Verified current alpha.2: On the DoH point (eddiedon) — agree on the threat model, one precision: The UDP53-hijack concern is real: under OpenClash/Clash TUN the transparent proxy intercepts plain UDP53, so One precision: "undici 有现成实现" is slightly optimistic — undici's Agent accepts a custom On allowDomains narrowing — agreed, and it's the constraint that keeps the triangle closed: exempt only the fake-ip range (198.18.0.0/15) and any user-declared CIDRs; keep RFC1918 / loopback / link-local rejected so #3051's security intent is preserved. That is also exactly what #4893 is asking for — a configurable allowlist that the SSRF guard still filters through. The test pattern is already there too ( |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Description
Title:
web-fetch-httpSSRF guard rejects every fetch under transparent-proxy fake-ip DNS (198.18.0.0/15) — no resolver/allowlist escape hatchSummary
Since v0.1.2, the new default public fetch backend (
@deepseek-ai/dsh-web-fetch-http) rejects all fetches to foreign domains when DSH runs on a network whose DNS answers with fake-ip addresses (198.18.0.0/15) — the standard DNS mode of transparent proxies (OpenClash / Clash / mihomo TUN), which is an extremely common home/office deployment in China. The domain resolves via the system resolver to a reserved-range IP, the SSRF guard correctly classifies it as non-public, and the whole answer set is rejected (WEB_BLOCKED_URL). There is no configuration to point the provider at a different resolver or to allowlist specific domains, so the shippedweb_fetchtool degrades to "domestic direct domains only".Environment
0.1.2-alpha.2(Windows 11, host-side — unrelated to the file sandbox)Resolve-DnsName example.com→198.18.21.38,github.com→198.18.0.7(fake-ip range), while CN-direct domains (e.g.www.baidu.com→180.101.51.73) resolve to real public IPsReproduction
Any tool bypassing the guard (e.g. Node
fetchinside the DSH sandbox) reaches the same URLs fine — the network path is healthy; only the guard's view of DNS is "poisoned" by fake-ip.Root cause (from
0.1.2-alpha.2sources)@deepseek-ai/dsh-web-fetch-http(src/network.ts, builtlib/index.js~L54-78):lookup(hostname, { all: true, order: "verbatim" })fromnode:dns/promises(getaddrinfo) → returns the fake-ip.isPublicIpAddress()= ipaddr.jsrange() === "unicast"; 198.18.0.0/15 (RFC 2544 benchmarking, used by Clash-family fake-ip) classifies as reserved → rejected.allowPrivate. README documents the caps (timeouts/bytes/chars) as the only knobs.Impact
web_fetchis effectively limited to domains that resolve to real public IPs (typically CN-direct domains). Foreign domains — the primary fetch targets (GitHub, docs, APIs) — always fail withWEB_BLOCKED_URL.Suggested directions (any one would fix this without weakening the SSRF guarantee)
resolver: <ip>or a DoH URL onweb-fetch-http. Resolution then returns real public IPs, the existing whole-set validation and connection pinning stay byte-for-byte identical — only the resolver is swappable. This is the most surgical fix and matches how other HTTP clients expose DNS overrides.allowDomains: ["github.com", "*.githubusercontent.com"]— an operator-asserted trust list that skips the non-public rejection for matching hostnames (still pinning to whatever the resolver returned). Clear, scoped, and loud in config.Workarounds in the wild (for other users hitting this)
fake-ip-filter/ dnsmasq whitelist) so they resolve to real IPs;fetch/MCP-based fetching tools instead of the shippedweb_fetch.Happy to test a build or provide more traces.
中文版
标题建议:
web-fetch-http的 SSRF 防护在透明代理 fake-ip DNS(198.18.0.0/15)环境下拒绝一切外域抓取,且无 resolver/allowlist 配置口一句话:0.1.2 默认启用的公网 WebFetch,在路由器 OpenClash/Clash fake-ip 模式(国内最常见的透明代理 DNS 部署)下,外域全部报
WEB_BLOCKED_URL——域名经系统解析拿到 198.18 假 IP,SSRF 校验按保留段拒绝整组结果。国内直连域名(真实 IP)不受影响。根因:
dsh-web-fetch-http用系统解析器(getaddrinfo)+ ipaddr.jsrange() === "unicast"判定 + 任一地址非公网即整组拒绝。这是正确的防 DNS rebinding 设计,但 fake-ip 部署下解析结果永远不可能通过校验,而配置面上没有任何换 resolver / 域名白名单的口子。建议(任一即可,均不削弱 SSRF 保证):
allowDomains信任清单:按域名豁免非公网拒绝,运营者显式断言;临时绕行:代理侧 fake-ip-filter 放行所需域名 / 本机 hosts 固定真实 IP / 用 node fetch 或 MCP 类抓取工具。
All reactions