WebSocket connect logs print the full base URL, leaking credentials embedded in openai_base_url
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
Summary
The Responses WebSocket transport logs the full connection URL on connect, success, and failure. When openai_base_url (or a model_providers.*.base_url) carries a credential — a capability-URL path segment, or URL userinfo — that secret ends up verbatim in the CLI's stderr / log output.
Local proxies and gateways in front of Codex commonly authenticate exactly this way, because the built-in openai provider's root openai_base_url override cannot carry a custom header, so the URL itself is the only place a local admission token can live (e.g. http://127.0.0.1:10100/t/<token>/v1).
Where
codex-rs/codex-api/src/endpoint/responses_websocket.rs (connect_websocket, as of 3d4d253f8f4a):
- https://github.com/openai/codex/blob/3d4d253f8f4a/codex-rs/codex-api/src/endpoint/responses_websocket.rs#L495 —
info!("connecting to websocket: {url}") info!("successfully connected to websocket: {url}, headers: {:?}", …)a few lines below- https://github.com/openai/codex/blob/3d4d253f8f4a/codex-rs/codex-api/src/endpoint/responses_websocket.rs#L516 —
error!("failed to connect to websocket: {err}, url: {url}")
The error! site is the worst of the three: it fires at default log level on every WS fallback (e.g. a gateway answering 426 Upgrade Required), so the secret lands in plain stderr during otherwise-normal operation, not just under RUST_LOG debugging.
Reproduction
- Point Codex at any local endpoint whose URL embeds a secret, e.g. in
~/.codex/config.toml:openai_base_url = "http://127.0.0.1:10100/t/SECRET-TOKEN/v1" - Have the endpoint reject the WebSocket upgrade (HTTP 426) so Codex falls back to HTTP.
- Run
codex exec "hi". Observed on codex-cli 0.147.0:ERROR codex_api::endpoint::responses_websocket: failed to connect to websocket: HTTP error: 426 Upgrade Required, url: ws://127.0.0.1:10100/t/SECRET-TOKEN/v1/responses
The HTTP fallback then works fine — which makes it easy to copy this stderr into bug reports, CI logs, or shared terminals without noticing the token.
Suggested fix
Redact the URL before logging at these sites: strip userinfo and query, and mask path segments (or at least log only scheme://host:port). Something like a small redacted_url(&Url) -> String helper used by all three call sites; map_ws_error may want the same treatment if the URL is embedded into the returned error string.
Happy to send a PR if that shape sounds right.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in codex-rs/codex-api/src/endpoint/responses_websocket.rs at connect_websocket and inspect the three URL-bearing log sites, then check map_ws_error for URL content in returned errors. Done means connection, success, failure, and fallback-related errors no longer expose credentials from the URL while retaining useful endpoint context.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100