fix(auth): loopback redirect URIs must match on any port (RFC 8252 §7.3) #2
Labels
No labels
blocked
waiting-on-julian
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
jlxq0/caldav-mcp#2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
Claude Code CLI cannot authenticate against
https://caldav-mcp.kampong.social/mcp:Cause
src/oauth_redirect.rs:23requires exact string equality:The deployed allowlist carries
http://localhost:8787/callback. Claude Code CLI does not use 8787. It picks a random free port per session and only falls back to a fixed one if the random draws all fail — the observed attempt usedhttp://localhost:3118/callback. No static entry can match, so the CLI is permanently locked out. The8787entry was written assuming a fixed port and has presumably never matched.RFC 8252 §7.3 is explicit that this is the server's bug, not the client's:
validate_redirect_urialready implements the loopback carve-out for the scheme check (cleartexthttppermitted on loopback hosts only). The port half of the same rule is missing.Fix
When an allowlist entry is a loopback
httpURI, compare scheme + host + path and ignore the port. Non-loopback entries keep exact matching — the port is a meaningful part of anhttpsor private-scheme callback and loosening it there would be a real hole.Tests to add:
http://localhost:8787/callbackallowlisted acceptshttp://localhost:3118/callbackhttp://localhost:3118/other(path still matters)http://127.0.0.1:3118/callbackunless127.0.0.1is separately listed (host still matters; RFC 8252 relaxes the port, not the host)https://claude.ai/api/mcp/auth_callbackstill rejectshttps://claude.ai:8443/api/mcp/auth_callbackSiblings
oauth_redirect.rsis copy-pasted, not shared. The same defect is incarddav-mcp,jmap-mcp,typst-mcpandm365-mcp— verified identical filenames in each repo, and none of their deployed allowlists carry a loopback entry that a CLI could hit either (m365-mcphas no loopback entry at all). Fix here first, then port.Workaround until this ships
Pin the client instead of the server:
MCP_OAUTH_CALLBACK_PORT=8787in the CLI's environment makes it reuse the already-allowlisted port.