Restrict cloud task credentials to trusted origins (#41403)

## Why

Cloud task requests can use saved ChatGPT credentials, so their destination must be constrained before authentication is loaded or any request is made.

## What changed

- Validate `CODEX_CLOUD_TASKS_BASE_URL` against trusted ChatGPT HTTPS origins on port 443 and reject URLs containing user information, queries, or fragments.
- Disable redirects for cloud task backend and environment-discovery clients so credentials are never forwarded to a redirect destination.
- Normalize the validated base URL before configuring authentication and HTTP clients.

## Testing

Add a CLI integration test that verifies a custom cloud backend is rejected without receiving a request, while the staging origin continues to use explicit token authentication.

GitOrigin-RevId: f0dddf363b4e44ea3530f81d9a817e978c15ead2
This commit is contained in:
Won Park authored and copyberry committed 2026-08-28 19:44:50 +00:00
1 parent d9511fb788
commit 3ae4225b17
5 files changed
+151 -8

No files matched your search

+3 -2
View File
@@ -53,6 +53,7 @@ async fn init_backend(user_agent_suffix: &str) -> anyhow::Result<BackendContext>
);
let base_url = std::env::var("CODEX_CLOUD_TASKS_BASE_URL")
.unwrap_or_else(|_| "https://chatgpt.com/backend-api".to_string());
let base_url = util::validate_chatgpt_base_url(&base_url)?;
set_user_agent_suffix(user_agent_suffix);
@@ -62,7 +63,7 @@ async fn init_backend(user_agent_suffix: &str) -> anyhow::Result<BackendContext>
return Ok(BackendContext {
backend: Arc::new(codex_cloud_tasks_mock_client::MockClient),
base_url,
environment_http: RouteAwareClientPool::new_without_request_logging(
environment_http: RouteAwareClientPool::new_without_redirects_or_request_logging(
http_client_factory,
ClientRouteClass::Api,
),
@@ -71,7 +72,7 @@ async fn init_backend(user_agent_suffix: &str) -> anyhow::Result<BackendContext>
let ua = get_codex_user_agent();
let (auth_manager, http_client_factory) = util::load_auth_manager(Some(base_url.clone())).await;
let environment_http = RouteAwareClientPool::new_without_request_logging(
let environment_http = RouteAwareClientPool::new_without_redirects_or_request_logging(
http_client_factory.clone(),
ClientRouteClass::Api,
);