fix: skip origin check when --client-id is supplied#6
fix: skip origin check when --client-id is supplied#6bowlofarugula wants to merge 3 commits intomasterfrom
Conversation
The `_validate_auth_server_origin` check (RFC 9728 §3) blocked servers where the resource server and authorization server are intentionally on different domains — e.g. an AWS AgentCore runtime (bedrock-agentcore. us-east-1.amazonaws.com) backed by Okta (oktapreview.com). The error message already said "use --client-id to bypass this check" but the code never implemented that bypass. When the caller supplies pre-registered credentials via --client-id, they have already established the trust relationship out-of-band. Skip the hostname comparison in that case and proceed with discovery normally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThis change modifies OAuth flow validation in Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@murl/auth.py`:
- Around line 508-514: The code currently skips _validate_auth_server_origin
whenever client_id is present, allowing a malicious resource server-controlled
issuer_url (from discover_auth_server_metadata / auth_servers[0]) to be used
without scrutiny; change authorize() so that when client_id is supplied you no
longer silently bypass validation: emit a clear warning naming the unvalidated
issuer_url (including the raw auth_servers[0] value) and log that DCR was
skipped, and additionally add an optional issuer_url / --auth-server parameter
to authorize()/CLI and, if provided, compare it against the discovered
issuer_url (or fail) instead of relying solely on client_id; keep the existing
_validate_auth_server_origin call when no explicit issuer is provided.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
…e supplied When --client-id is passed the caller has established the trust relationship out-of-band (e.g. AWS AgentCore + Okta: resource server on *.amazonaws.com, auth server on *.okta.com). The same-origin heuristic would only block legitimate cross-domain deployments in this case, since PKCE + state still provide the attack-surface protection the check was meant for. Also drops the inaccurate "RFC 9728 §3" citation from the inline comment (§3 defines Protected Resource Metadata format, not origin-matching). Adds a regression test for the cross-domain + client_id path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent_id A compromised resource server can advertise any authorization_servers URL. When --client-id bypasses the same-origin check, print a warning naming the unvalidated issuer so the user can confirm it's their expected provider before their browser opens. PKCE+state still protect code injection and CSRF, but naming the issuer is the only guard against phishing via a malicious redirect. Also fixes test to assert the warning is emitted and contains the issuer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
_validate_auth_server_originwas supposed to be bypassable via--client-id(the error message said so), but the bypass was never implemented — the check always ran regardless of whether pre-registered credentials were supplied.if not client_id:conditionmurlrefused to connect to MCP servers where the resource server and auth server are intentionally on different domains — e.g. AWS AgentCore (.amazonaws.com) + Okta (.okta.com)What changed
murl/auth.py: wrap_validate_auth_server_origincall inif not client_id:; when skipped, emit a warning naming the unvalidated issuer URL so the user can verify it's their expected providermurl/auth.py: drop the inaccurate "RFC 9728 §3" citation — §3 defines Protected Resource Metadata format, not origin-matching; the check is a murl heuristic, not a spec mandatemurl/auth.py: update the error message in_validate_auth_server_originto remove the now-accurate "use --client-id to bypass" guidance (which now works)tests/test_auth.py: add regression test for cross-domain auth server +client_idsupplied — asserts noOAuthErrorand that the warning is emitted naming the issuerSecurity considerations
The same-origin check prevents a malicious resource server from advertising a foreign AS and redirecting a victim's browser there. Skipping it is a real trade-off:
--client-idis NOT set: The check is enforced. murl rejects any resource server whoseauthorization_serverslist points off-domain.--client-idIS set: The check is skipped. A compromised resource server could still advertise an attacker-controlled AS. We print a warning naming the issuer — the user's best defense is to verify the domain in the warning (and, when the browser opens, in the address bar) before entering credentials. PKCE + state remain in force and protect against code injection and CSRF but do not protect against credential phishing via a lookalike AS.The correct fix for deployments that want a stronger guarantee is an explicit
--auth-serverflag that pins the expected AS and fails if discovery returns something different. That's out of scope for this PR (filed as a follow-up) — but the warning here ensures users are not silently exposed.Test plan
uv run pytest tests/test_auth.py— all 62 tests passmurl --client-id <id> --client-secret <secret> --callback-port <port> <agentcore-url>no longer fails with "authorization server hostname does not match", and prints a warning naming the Okta issuer