fix(anthropic): keep OAuth callback on loopback#96917
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 5, 2026, 8:20 PM ET / 00:20 UTC. Summary PR surface: Source +12, Tests +82, Docs +1. Total +95 across 3 files. Reproducibility: yes. Source inspection on current main and v2026.6.11 shows the listener host can diverge from the fixed localhost redirect URI; I did not run a live Anthropic login. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the narrow loopback-only callback fix after maintainers accept the fail-closed auth-env compatibility tradeoff and current-head real CLI/login proof demonstrates invalid-host rejection plus at least one permitted loopback callback path. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection on current main and v2026.6.11 shows the listener host can diverge from the fixed localhost redirect URI; I did not run a live Anthropic login. Is this the best way to solve the issue? Unclear until maintainer acceptance and real proof. The patch is a narrow and plausible hardening fix, but the fail-closed environment change and fixed-localhost provider contract need explicit acceptance before merge. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 04a6a318591c. Label changesLabel justifications:
Evidence reviewedPR surface: Source +12, Tests +82, Docs +1. Total +95 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 (5 earlier review cycles)
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
d938725 to
34d4036
Compare
ffbe0ba to
8cf8fe4
Compare
1993302 to
0aa16e3
Compare
…d derive redirect URI
…atch shipped behavior
Co-authored-by: xialonglee <[email protected]>
Co-authored-by: xialonglee <[email protected]>
Co-authored-by: xialonglee <[email protected]>
0aa16e3 to
36d34e7
Compare
|
Land-ready at exact head The callback listener and provider redirect are separate contracts: the listener binds only to Proof:
No live Anthropic token exchange was run because that requires an interactive user credential; the network callback and redirect propagation are exercised end to end with the mocked token endpoint. |
|
Merged via squash.
|
* fix(anthropic): restrict OAuth callback host to loopback addresses and derive redirect URI * fix(anthropic): restore localhost as default OAuth callback host to match shipped behavior * fix(anthropic): defer OAuth callback host validation to login path * refactor(anthropic): bind callback host independently Co-authored-by: xialonglee <[email protected]> * docs(changelog): note Anthropic callback fix Co-authored-by: xialonglee <[email protected]> * fix(oauth): satisfy Anthropic callback lint Co-authored-by: xialonglee <[email protected]> * chore: defer Anthropic OAuth changelog --------- Co-authored-by: Peter Steinberger <[email protected]>
* fix(anthropic): restrict OAuth callback host to loopback addresses and derive redirect URI * fix(anthropic): restore localhost as default OAuth callback host to match shipped behavior * fix(anthropic): defer OAuth callback host validation to login path * refactor(anthropic): bind callback host independently Co-authored-by: xialonglee <[email protected]> * docs(changelog): note Anthropic callback fix Co-authored-by: xialonglee <[email protected]> * fix(oauth): satisfy Anthropic callback lint Co-authored-by: xialonglee <[email protected]> * chore: defer Anthropic OAuth changelog --------- Co-authored-by: Peter Steinberger <[email protected]>
What Problem This Solves
Anthropic OAuth allowed the local callback listener host to be configured without validating that it was loopback-only. The earlier PR revision also derived the OAuth
redirect_urifrom that bind host, but Anthropic's current client contract requireshttp://localhost:53692/callbackeven when the listener binds an equivalent loopback address.Fixes #96485.
Why This Change Was Made
The callback bind address and provider redirect identity are separate contracts:
OPENCLAW_OAUTH_CALLBACK_HOSTis validated only when login starts and acceptslocalhost,127.0.0.1, or::1;127.0.0.1and may bind any accepted loopback address;http://localhost:53692/callback.This is smaller and safer than deriving the redirect URI from local bind configuration. Direct inspection of the installed Claude Code 2.1.201 client confirmed the same contract: localhost redirect URI, loopback listener. Anthropic's public Claude Code issue #11469 documents the localhost callback behavior as well.
User Impact
Invalid/non-loopback callback hosts fail only when Anthropic login starts, so unrelated CLI imports and commands remain unaffected. Operators can still choose IPv4 or IPv6 loopback binding without changing the provider-visible redirect URI.
Evidence
tbx_01kwt6qx4r4ptdbg4ps3yhnj55:src/llm/utils/oauth/anthropic.test.ts, 11/11 passed.127.0.0.1:53692, sends an HTTP callback, and verifies both authorization and token-exchange requests use the fixed localhost redirect URI.oxfmt --checkpassed for source and tests.git diff --checkpassed.Live Anthropic token exchange was not run because it requires an interactive user credential. No docs change is needed; the Unreleased changelog entry is included.