openai / openai/codex

WebSocket connect logs print the full base URL, leaking credentials embedded in openai_base_url

Open
#37,988 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI connectivity
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):

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

  1. 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"
    
  2. Have the endpoint reject the WebSocket upgrade (HTTP 426) so Codex falls back to HTTP.
  3. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.