fix(net): harden trusted env proxy fetch guard and add explicit web_fetch opt-in#58034
fix(net): harden trusted env proxy fetch guard and add explicit web_fetch opt-in#58034cosmicnet wants to merge 1 commit intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR fixes a latent bug where The fix correctly restructures the dispatcher-selection logic in Key findings:
Confidence Score: 4/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/infra/net/fetch-guard.ssrf.test.ts
Line: 371-376
Comment:
**Missing `ALL_PROXY`/`all_proxy` stubs weaken test isolation**
`hasProxyEnvConfigured()` iterates over all six keys in `PROXY_ENV_KEYS`, which includes `ALL_PROXY` and `all_proxy`. This test only stubs four of them. If a CI host (or a developer's machine) has `ALL_PROXY` or `all_proxy` set, `hasProxyEnvConfigured()` returns `true`, `canUseTrustedEnvProxy` becomes `true`, and the code takes the proxy path instead of the DNS-pinning path the test expects — causing the test to either fail or silently validate wrong behavior.
Since the goal of this test is to lock in the fallback behaviour with high confidence ("no proxy env var exists"), all six keys need to be cleared:
```suggestion
// Ensure no proxy vars leak from the test host
vi.stubEnv("HTTP_PROXY", "");
vi.stubEnv("HTTPS_PROXY", "");
vi.stubEnv("ALL_PROXY", "");
vi.stubEnv("http_proxy", "");
vi.stubEnv("https_proxy", "");
vi.stubEnv("all_proxy", "");
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(net): skip DNS pinning when routing ..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1e0e2788ef
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Updates the SSRF/DNS pinning flow in the network fetch guard so that when routing through a trusted environment proxy, local DNS resolution (and associated pinning) is skipped—unblocking proxy-only sandbox environments where UDP DNS is unavailable.
Changes:
- Restructures
fetchWithSsrFGuardto branch early between trusted env-proxy dispatch and direct/pinned-DNS dispatch. - Adds unit tests to ensure DNS resolution is skipped in trusted env-proxy mode and that the code falls back to DNS pinning when no proxy env is configured.
- Enables
useEnvProxy: truefor theweb_fetchtool so it opts into env-proxy routing when available.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/infra/net/fetch-guard.ts |
Moves DNS pinning/lookup into the non-proxy path; uses EnvHttpProxyAgent when trusted env proxy is active. |
src/infra/net/fetch-guard.ssrf.test.ts |
Adds tests covering DNS-skip behavior in trusted env proxy mode and fallback behavior when no proxy env is set. |
src/agents/tools/web-fetch.ts |
Opts web_fetch into env-proxy routing via useEnvProxy: true. |
1e0e278 to
ba4a2a8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba4a2a8b1f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
ba4a2a8 to
b1cf12c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1cf12cffc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
b1cf12c to
f291d7a
Compare
f291d7a to
d998d26
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d998d26180
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
d998d26 to
b296e4e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b296e4e671
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
b296e4e to
3eb849d
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3eb849dd5e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Note: #59007 was opened addressing the same root cause. That PR moves DNS resolution into the non-proxy branch (same structural fix as here) but does not include:
Codex flagged the Size on this pull changed from S to M largely due to increased test coverage. |
|
Heads up — #59007 (skip DNS pinning before trusted env proxy dispatch) merged on 2026-04-08, which covers the core DNS-before-proxy ordering fix that this PR also addresses. This PR has additional protocol-aware detection logic that #59007 doesn't include. Is there interest in continuing with that extra coverage, or should this be closed as superseded? Happy either way — just want to make sure it doesn't go stale without a decision. |
|
@mjamiv Yeah, I saw that. I replied on your comment here with the changes I'm currently working on for this branch: |
3eb849d to
c3c471e
Compare
|
I’ve rebased this branch onto the latest main, which is moving pretty quickly. The change to make web_fetch respect a trusted proxy for DNS resolution is now behind an explicit config value, so the default behaviour remains unchanged and SSRF protections stay in place unless it is deliberately enabled. @mjamiv does this provide what you need? |
|
This PR also closes out #63565 (" |
2c25c56 to
f1b8f45
Compare
|
Thanks, that makes sense. #63565 is the same proxy-only sandbox failure mode this branch is narrowing down, so I’ve added it to the Linked Issue/PR list for review routing. I have now force-pushed the rebased branch again on top of current I’d definitely welcome a proxy-only sandbox test on your side if you have time. That is the exact deployment shape this branch is intended to cover. The live verification I already ran against a completely fresh bleeding-edge NemoClaw / OpenShell / OpenClaw build and deploy showed that, once |
f1b8f45 to
5df6a0f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5df6a0f6fc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Tested this branch end-to-end in a proxy-only sandbox deployment (HTTP CONNECT egress, UDP DNS blocked,
This covers the shape of environment described in #63565. Rolled the test environment back to stock afterward, no residual changes. Happy to re-run if you rebase or want additional scenarios. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 036d6c8648
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Hi @cosmicnet, just checking in on this PR. This fix seems important for users running OpenClaw behind Clash or other transparent proxies where UDP is blocked and all DNS must go through the proxy. Could you let us know if there's anything blocking this from being merged, or if it needs any additional information from the maintainers? |
|
@smallmj thanks for checking in. From my side, I do not think there is any substantive author-side blocker left on this branch. The change is implemented, I have manually verified it in a live OpenShell/NemoClaw deployment, and @mjamiv has independently verified it end to end in a proxy-only sandbox. I do think part of the confusion here is that #59007 was treated as superseding this PR, but it did not actually pull in all of the remaining work from this branch. It landed the narrower DNS-before-proxy ordering fix, but it did not include the explicit So from my side, I believe this is ready to pull in. If there is still a specific maintainer concern blocking merge, I would appreciate a pointer to it. |
Comprehensive Proxy Test Results (2026-04-13)Test Environment
Test 1: Without Tun mode (proxy env vars not set)curl with explicit -x flag (proxy works): curl without proxy (direct): web_fetch tool: Conclusion: web_fetch does not use proxy even when proxy is working for curl. Test 2: With Tun mode + DNS override enabled (no HTTPS_PROXY env var set)All DNS now routes through Clash TUN, which returns 198.18.x.x (RFC 2544 benchmark IP range) for most domains. curl direct (Tun catches all): web_fetch: Root cause: Clash TUN DNS returns 198.18.x.x (benchmark IPs). OpenClaw SSRF guard correctly blocks these as special-use addresses. Conclusion: Tun mode breaks web_fetch via DNS + SSRF interaction. Test 3: Tun mode OFF, DNS override OFF, HTTPS_PROXY env var set in systemctlProperly injected proxy env into Gateway: systemctl --user set-environment HTTPS_PROXY=http://127.0.0.1:7897
systemctl --user set-environment ALL_PROXY=http://127.0.0.1:7897
systemctl --user restart openclaw-gatewayVerification: curl (no -x flag, Tun off): web_fetch: Conclusion: Even with HTTPS_PROXY correctly set in the Gateway process environment, web_fetch still does not use the proxy. This confirms web_fetch itself does not read HTTPS_PROXY/ALL_PROXY env vars — it uses Node.js built-in fetch which goes direct. Summary
This is why PR #58034 is needed. The core issue is not the environment or DNS — it's that web_fetch does not respect HTTPS_PROXY. The Additional note from cosmicnet: PR #59007 merged the DNS-before-proxy ordering fix for the core network layer, but did NOT include the web_fetch opt-in. This PR (#58034) adds that missing piece. |
755cbf6 to
9307bc6
Compare
|
Rebased onto current main and force-pushed the branch. I reran the affected coverage for the edited paths only: the NO_PROXY matcher, fetch guard SSRF path, web_fetch trusted-env-proxy path, and the config-doc baseline check. Those all pass on the rebased branch. I have not rerun the full suite. The branch still carries the web_fetch-specific trusted env proxy opt-in and docs on top of the upstream proxy/fetch changes already on main. |
9307bc6 to
d063e40
Compare
|
For context, I think this branch addresses a different case from #60785 (which was just closed). #60785 is about fake-IP setups via This branch is aimed at proxy-only environments where local DNS is blocked or unavailable and |
|
Codex review: needs maintainer review before merge. What this changes: The PR adds a default-off Maintainer follow-up before merge: This is useful active contributor work, but it is dirty against current main and changes SSRF/trusted-proxy network semantics, so maintainers should review the trust boundary and rebase before landing rather than sending it to autonomous repair. Security review: Security review cleared: The diff changes network routing, but the reviewed design keeps the new path default-off, protocol/NO_PROXY gated, and hostname-policy guarded; no concrete secrets, CI, dependency, or supply-chain regression was found. Review detailsBest possible solution: Land a rebased version if maintainers accept the trust boundary: keep Do we have a high-confidence way to reproduce the issue? Yes. The high-confidence reproduction is a proxy-only sandbox with Is this the best way to solve the issue? Likely yes, subject to maintainer trust-boundary approval and a clean rebase. A default-off config knob with protocol-aware proxy gating, Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 51affb81b9a5. |
d063e40 to
bd87eae
Compare
|
Thanks. Latest push is I believe the concrete implementation pieces called out here are now present on the branch:
Focused local verification after the final push contents:
All passed locally. On the Firecrawl/provider fallback question: I left that as an intentional scope boundary for this PR. This branch makes the built-in |
bd87eae to
6bb5882
Compare
6bb5882 to
b93c8f6
Compare
|
Post-#76887 status: still relevant, but this remains a separate Current branch state is still |
|
Landed the maintainer-side version on main in 66336bf. Kept the setting default-off as Verification before landing:
Thanks @cosmicnet and @mjamiv. |
This PR now layers on top of merged #59007 rather than competing with it.
When using a trusted environment proxy, web_fetch can now skip local DNS pinning only when explicitly enabled with tools.web.fetch.useTrustedEnvProxy. The default behaviour stays unchanged. In the trusted-proxy path, hostname policy checks still run before dispatch, and requests fall back to the pinned-DNS path when no matching HTTP(S) proxy env var applies or when NO_PROXY excludes the target.
Local DNS fails in sandboxed environments where UDP is blocked and all traffic must route through the proxy, but skipping local DNS needs to stay narrow and explicit so SSRF protections do not get weakened by default.
Summary
Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Note: #59007 merged the core DNS-before-proxy ordering fix. This PR keeps the remaining hardening and behaviour-shaping changes on top of that: protocol-aware proxy detection, NO_PROXY fallback, pre-DNS hostname policy checks in the trusted-proxy path, the explicit web_fetch config opt-in, and the user-facing documentation for that new setting.
Root Cause / Regression History (if applicable)
Regression Test Plan (if applicable)
User-visible / Behaviour Changes
Diagram (if applicable)
Security Impact (required)
Repro + Verification
Environment
Steps
Expected
Actual
Evidence
Verification performed for the rebased branch:
pnpm config:docs:checkpasses after the schema/docs updatepnpm testwas run on updatedmainand on this branch after rebasing; after refreshing the stale generated base-schema file, the visible failures on this branch matched the currentmainbaseline, with no extra visible branch-only failure identifiedtools.web.fetch.useTrustedEnvProxyletweb_fetchreach upstream services through the trusted env proxy path; remainingexample.com-style failures traced to Bug(proxy): is the sandbox proxy’s upstream TLS CA bundle too limited for some ordinary public HTTPS sites? Example repros included NVIDIA/OpenShell#813 rather than this OpenClaw changeHuman Verification (required)
NO_PROXYfallback, hostname policy enforcement in the trusted-proxy path, the explicitweb_fetchopt-in, and the accompanying config/docs surfaces. The trusted env proxy path was also exercised in a completely fresh bleeding-edge NemoClaw / OpenShell / OpenClaw build and deploy.NO_PROXY; defaultweb_fetchbehaviour when the opt-in is not enabled.Review Conversations
Compatibility / Migration
Risks and Mitigations