#22644: feat(web-fetch): add allowPrivateNetwork config for web_fetch
agents
size: XS
Cluster:
Web Search Provider Enhancements
## Summary
- **Problem:** `web_fetch` had no way to allow access to private/internal network URLs; SSRF guard always blocked them.
- **Why it matters:** Users running OpenClaw in trusted environments (e.g. fetching from internal docs or local services) need an opt-in to allow private network targets.
- **What changed:** Added `tools.web.fetch.allowPrivateNetwork` config; when `true`, `web_fetch` passes `policy: { allowPrivateNetwork: true }` to `fetchWithSsrFGuard`. Default remains `false` (private networks blocked).
- **What did NOT change:** Default behavior, Firecrawl path, or other tools; only `web_fetch` and its config/schema.
## Context
- `web_fetch` uses `fetchWithSsrFGuard`, which enforces SSRF policy via `resolvePinnedHostnameWithPolicy`. Private/internal hosts (localhost, 10.x, 192.168.x, etc.) are blocked unless the caller passes a policy with `allowPrivateNetwork: true`.
- Other parts of the repo already support this opt-in (e.g. `browser.ssrfPolicy.allowPrivateNetwork`, `channels.tlon.allowPrivateNetwork`). `web_fetch` previously did not expose any config and always used the default (block private).
## Changes
- **Config:** Added `tools.web.fetch.allowPrivateNetwork` to zod schema (`ToolsWebFetchSchema`), TypeScript types (`types.tools.ts`), and UI hints (`schema.labels.ts`, `schema.help.ts`).
- **Runtime:** In `web-fetch.ts`, added `resolveFetchAllowPrivateNetwork()`, threaded `allowPrivateNetwork` into `WebFetchRuntimeParams`, and pass `policy: { allowPrivateNetwork: true }` into `fetchWithSsrFGuard` when enabled; otherwise omit policy (default block).
## Change Type (select all)
- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [x] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [ ] Integrations
- [x] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## User-visible / Behavior Changes
- New config: `tools.web.fetch.allowPrivateNetwork` (boolean, optional). Default: `false`. When set to `true`, `web_fetch` may fetch private/internal network addresses (localhost, 10.x, 192.168.x, etc.). Schema labels and help text added for UI.
## Security Impact (required)
- New permissions/capabilities? **Yes** — opt-in capability to fetch private/internal URLs.
- Secrets/tokens handling changed? **No**
- New/changed network calls? **No** (same fetch surface; destination allowlist is relaxed only when opted in).
- Command/tool execution surface changed? **No**
- Data access scope changed? **Yes** — when `allowPrivateNetwork: true`, tool can reach internal hosts.
- **Risk + mitigation:** Risk: operators might enable this in untrusted environments and expose internal services. Mitigation: default is `false`; explicit config required; consistent with existing patterns (e.g. `channels.tlon.allowPrivateNetwork`, browser `ssrfPolicy.allowPrivateNetwork`).
## Human Verification (required)
- **Verified scenarios:** Config resolution (default false, explicit true); `fetchWithSsrFGuard` receives `policy` only when enabled.
- **Edge cases checked:** Missing/undefined config defaults to false; type/schema include new key.
- **What you did not verify:** Live fetch to real private IP (test uses mocks).
## Compatibility / Migration
- Backward compatible? **Yes**
- Config/env changes? **Yes** — new optional key `tools.web.fetch.allowPrivateNetwork`.
- Migration needed? **No**
- If yes, exact upgrade steps: N/A
## Failure Recovery (if this breaks)
- **How to disable/revert:** Set `tools.web.fetch.allowPrivateNetwork: false` or remove the key; or revert the PR.
- **Files/config to restore:** Revert changes in config schema, types, and `src/agents/tools/web-fetch.ts` / test.
- **Known bad symptoms:** If private fetches still blocked when enabled, check that config is loaded and passed into `createWebFetchTool`.
## Risks and Mitigations
- **Risk:** Misuse of `allowPrivateNetwork: true` in shared/untrusted environments could expose internal services.
- **Mitigation:** Default off; documented as opt-in; aligned with existing SSRF opt-in patterns in the repo.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added opt-in `tools.web.fetch.allowPrivateNetwork` config to allow `web_fetch` to access private/internal network addresses (localhost, 10.x, 192.168.x, etc.) in trusted environments.
- Introduced `allowPrivateNetwork` boolean config field (default: `false`) across schema (`zod-schema.agent-runtime.ts`), types (`types.tools.ts`), and UI metadata (`schema.labels.ts`, `schema.help.ts`)
- Implemented `resolveFetchAllowPrivateNetwork()` helper following existing resolver patterns
- Passes `policy: { allowPrivateNetwork: true }` to `fetchWithSsrFGuard` when enabled, otherwise omits policy (defaults to blocking private networks)
- Consistent with existing patterns: `browser.ssrfPolicy.allowPrivateNetwork` and `channels.tlon.allowPrivateNetwork`
- No behavioral changes to default configuration (still blocks private networks)
- No tests added for the new configuration option
<h3>Confidence Score: 5/5</h3>
- Safe to merge - well-scoped security enhancement with appropriate defaults
- Implementation follows established patterns for SSRF policy configuration (matches browser and tlon channel implementations), maintains secure defaults (private networks blocked unless explicitly enabled), and integrates cleanly with existing `fetchWithSsrFGuard` infrastructure without changing default behavior
- No files require special attention
<sub>Last reviewed commit: eab9bef</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#19042: Security: add URL allowlist for web_search and web_fetch
by smartprogrammer93 · 2026-02-17
81.5%
#19942: feat(telegram): configurable SSRF policy for media fetch
by onewesong · 2026-02-18
79.1%
#11086: fix(mattermost): allow private network for inbound media download
by oskarmodig · 2026-02-07
76.3%
#19525: security: add SSRF validation for external URLs
by Mozzzaic · 2026-02-17
76.3%
#21741: fix(gateway): allow plaintext ws:// for Docker/private network addr...
by Joe3112 · 2026-02-20
75.4%
#23598: fix(msteams): add SSRF protection to attachment downloads via redir...
by lewiswigmore · 2026-02-22
74.0%
#15251: feat(web-fetch): send Accept: text/markdown header for Cloudflare M...
by wujieli0207 · 2026-02-13
73.6%
#21697: fix(gateway): unblock local spawn pairing and gated private-LAN ws
by rjuanluis · 2026-02-20
73.3%
#16590: fix(web-fetch): use bot UA for markdown to enable Cloudflare LLM co...
by Imccccc · 2026-02-14
73.3%
#8228: fix(link-understanding): block private IPs and internal hostnames i...
by yubrew · 2026-02-03
72.9%