fix(ssrf): block loopback addresses for trusted hostname origins#100835
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 7, 2026, 6:06 AM ET / 10:06 UTC. Summary PR surface: Source +31, Tests +89. Total +120 across 3 files. Reproducibility: yes. at source level. Current main promotes matching Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the tightened trusted-host loopback guard after the owning maintainer accepts the fail-closed compatibility behavior and exact-head CI finishes green. Do we have a high-confidence way to reproduce the issue? Yes, at source level. Current main promotes matching Is this the best way to solve the issue? Yes, mostly. The PR fixes the central helper used by both DNS resolution and dispatcher override paths with existing net-policy parsing; the remaining question is maintainer acceptance of the fail-closed compatibility boundary. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 395fbb8eb631. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +31, Tests +89. Total +120 across 3 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (7 earlier review cycles)
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
@clawsweeper re-review |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
…localhost hostnames
afcffd4 to
f4331d1
Compare
|
Land-ready maintainer repair complete on exact head What changed:
Proof:
Known proof gaps: none for this bounded resolver/dispatcher policy change. |
|
Merged via squash.
|
The SSRF loopback tightening in openclaw#100835 blocked loopback addresses for trusted hostnames, but the browser navigation guard's explicit allowlist (allowedHostnames) should permit loopback for explicitly allowed hosts. Pass the SSRF policy to assertAllowedTrustedHostnameResolvedAddressesOrThrow so it can check the allowedHostnames list in addition to explicit loopback hostnames. Fixes openclaw#101965
The SSRF loopback tightening in openclaw#100835 blocked loopback addresses for trusted hostnames, but the browser navigation guard's explicit allowlist (allowedHostnames) should permit loopback for explicitly allowed hosts. Pass the SSRF policy to assertAllowedTrustedHostnameResolvedAddressesOrThrow so it can check the allowedHostnames list in addition to explicit loopback hostnames. Fixes openclaw#101965
…nclaw#100835) * fix(ssrf): block loopback addresses for trusted hostname origins * fix(ssrf): allow loopback resolution for explicitly trusted loopback/localhost hostnames * refactor(cron): remove unrelated cron session option changes from ssrf branch * test(ssrf): add explicit loopback-origin allow tests to close ClawSweeper proof gap * test(ssrf): add real gateway runtime proof script for loopback rebinding * fix(ssrf): harden trusted-host loopback checks --------- Co-authored-by: Peter Steinberger <[email protected]>
…nclaw#100835) * fix(ssrf): block loopback addresses for trusted hostname origins * fix(ssrf): allow loopback resolution for explicitly trusted loopback/localhost hostnames * refactor(cron): remove unrelated cron session option changes from ssrf branch * test(ssrf): add explicit loopback-origin allow tests to close ClawSweeper proof gap * test(ssrf): add real gateway runtime proof script for loopback rebinding * fix(ssrf): harden trusted-host loopback checks --------- Co-authored-by: Peter Steinberger <[email protected]>
…nclaw#100835) * fix(ssrf): block loopback addresses for trusted hostname origins * fix(ssrf): allow loopback resolution for explicitly trusted loopback/localhost hostnames * refactor(cron): remove unrelated cron session option changes from ssrf branch * test(ssrf): add explicit loopback-origin allow tests to close ClawSweeper proof gap * test(ssrf): add real gateway runtime proof script for loopback rebinding * fix(ssrf): harden trusted-host loopback checks --------- Co-authored-by: Peter Steinberger <[email protected]> (cherry picked from commit a00e9fc)
Note
AI-Assisted Contribution: This PR was prepared and validated with the assistance of an AI coding assistant (Antigravity/Gemini).
What Problem This Solves
This PR resolves a security boundary bypass where hostnames configured as trusted/allowed origins (and promoted to
allowedHostnamesduring a request) bypass loopback DNS checks. BecauseassertAllowedTrustedHostnameResolvedAddressesOrThrowdid not block loopback addresses, a trusted non-localhost hostname (e.g.lan-llm.corp.internal) resolving/rebinding to a loopback IP (127.0.0.1or::1) would be allowed. This exposes the gateway to DNS rebinding attacks targeting localhost services.Faulty code snippet in ssrf.ts:
Why This Change Was Made
The change blocks loopback resolutions for trusted hostnames unless the hostname itself is explicitly a localhost origin (e.g.
localhost,127.0.0.1,::1, or matching*.localhost), which is required for legitimate local-dev provider configurations.Fixed code snippet in ssrf.ts:
User Impact
Tightens the gateway's SSRF boundary to protect against malicious DNS rebinding to local-host services while keeping support for explicit local development configurations.
Important
Upgrade compatibility note:
Non-localhost custom or private local provider aliases (e.g., pointing to custom local DNS names resolving to
127.0.0.1) will now be blocked unless users explicitly opt in by enablingallowPrivateNetworkin their configuration policy or use a localhost hostname.Evidence
Unit Tests / Verification Suite
src/plugin-sdk/ssrf-policy.test.tsfully cover all cases.Real Behavior Proof
Scenario A — [Attack/Bad Input]: Blocked ✅
Rebinding a trusted private origin to loopback IPv4/IPv6 is successfully blocked.
Test cases:
rebinding a trusted private origin to a loopback IP is rejectedrebinding a trusted private origin to IPv6 loopback is rejectedScenario B — [Legitimate Input]: Still Allowed ✅
Explicit localhost/127.0.0.1 origins resolving to loopback are still permitted.
Test cases:
explicit localhost origin resolving to 127.0.0.1 is still allowedexplicit 127.0.0.1 origin resolving to loopback is still allowedScenario C — [Pre-existing Rejections]: Unaffected ✅
Pre-existing rejections to cloud metadata or link-local IPs remain blocked.
Test cases:
rebinding a trusted private origin to a metadata IP is still rejectedrejects plugin-supplied allowedOrigins entry: AWS/EC2 IMDS IPv4 literalrejects plugin-supplied allowedOrigins entry: GCP metadata canonical hostnameFull Test Run (Real OpenClaw Runner Output)
Run command:
OPENCLAW_VITEST_INCLUDE_FILE=/tmp/ssrf-test.json node scripts/run-vitest.mjs run --config test/vitest/vitest.unit-fast.config.tsBranch name:
fix/4.2-ssrf-trusted-hostname-loopback-checkCommit SHA:
afcffd44432d08a98d678220741e49e24e772a6eTimestamp:
2026-07-07T15:07:15+05:30Real Gateway Runtime Proof
Run command:
node --import tsx scripts/proof/proof-ssrf-loopback.mtsTimestamp:
2026-07-07T15:06:56+05:30