[RIP-SEC] MCP OAuth login opens the server-supplied `authorization_endpoint` with `webbrowser::open` and no URL-scheme allowlist
Summary
During MCP OAuth login, Codex builds an authorization URL from the OAuth metadata'sauthorization_endpoint — a value served by the (untrusted) MCP server — and passes it towebbrowser::open with no scheme validation. A malicious or MITM'd MCP server can setauthorization_endpoint to a non-web scheme (file:, smb:, search-ms:, a custom app://), and
Codex hands that URL to the victim's OS default handler.
Where
codex-rs/rmcp-client/src/perform_oauth_login.rs—webbrowser::open(auth_url)(no scheme check);
auth_url is built from oauth_state.get_authorization_url() whose base is the server-supplied
authorization_endpoint.
- Reachable via
codex mcp login <server>and the automatic skill-MCP-dependency install path
(launch_browser = true).
- Present on current
main.
Reproduction
Standing up a local OAuth-metadata server whose authorization_endpoint is a dangerous-scheme URL and
running the real start_authorization + get_authorization_url shows the attacker scheme survives
intact into the string passed to webbrowser::open (verified without invoking webbrowser::open):
| server authorization_endpoint | resulting authorization_url scheme |
|---|---|
| file:///etc/passwd | file |
| smb://attacker.example/share | smb |
| calculatorapp://run?x=1 | calculatorapp |
| search-ms:query=secret&crumb=location | search-ms |
Neither codex-rs nor the vendored rmcp URL construction rejects the scheme.
Impact
A malicious/MITM MCP server can cause Codex to invoke the victim's OS handler for an arbitrary URL
scheme (e.g. search-ms: opens Explorer search on Windows; smb: can trigger an outbound
SMB/NTLM connection; a registered custom handler is launched). Protocol-handler drive-by, not RCE;
requires the victim to add/trust the server or install a skill that pulls it in.
Suggested fix
Validate the scheme against an allowlist (https; http only for loopback) before webbrowser::open,
and reject non-web schemes when accepting authorization_endpoint from discovery.
---
Found with the rust-in-peace pipeline
(AI-assisted Rust vulnerability research).
1 Comment
Candidate fix (with a regression test) for this issue. I can't open a PR directly —
openai/codexrestricts pull requests to collaborators — so the patch is inline below,and also on a branch you can pull/cherry-pick: https://github.com/scadastrangelove/codex/tree/codex-mcp-oauth-scheme-allowlist
<details><summary>Patch (
git diff)</summary></details>
Built and tested on
main@c87a218with toolchain 1.95.0._Found with the rust-in-peace pipeline._