From f3bfaca3c1f1004f6c7707d8f781ce43007a0b39 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Wed, 8 Jul 2026 15:45:57 -0700 Subject: [PATCH] Clarify device-code phishing warning (#31648) ## Why The existing device-code warning does not help users distinguish a login they initiated from a phishing attempt. The warning should tell users to stop when the code came from a website or another person. ## What changed - Updated the warning in the direct CLI and TUI device-code login flows with actionable guidance. - Added focused coverage for the styled direct CLI prompt. --- codex-rs/login/src/device_code_auth.rs | 17 +++++++++++++---- codex-rs/login/src/device_code_auth_tests.rs | 10 ++++++++++ .../onboarding/auth/headless_chatgpt_login.rs | 2 +- 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 codex-rs/login/src/device_code_auth_tests.rs diff --git a/codex-rs/login/src/device_code_auth.rs b/codex-rs/login/src/device_code_auth.rs index 70e6dff225..e7a31916a5 100644 --- a/codex-rs/login/src/device_code_auth.rs +++ b/codex-rs/login/src/device_code_auth.rs @@ -145,15 +145,20 @@ async fn poll_for_token( } } -fn print_device_code_prompt(verification_url: &str, code: &str) { +fn device_code_prompt(verification_url: &str, code: &str) -> String { let version = env!("CARGO_PKG_VERSION"); - println!( + format!( "\nWelcome to Codex [v{ANSI_GRAY}{version}{ANSI_RESET}]\n{ANSI_GRAY}OpenAI's command-line coding agent{ANSI_RESET}\n\ \nFollow these steps to sign in with ChatGPT using device code authorization:\n\ \n1. Open this link in your browser and sign in to your account\n {ANSI_BLUE}{verification_url}{ANSI_RESET}\n\ \n2. Enter this one-time code {ANSI_GRAY}(expires in 15 minutes){ANSI_RESET}\n {ANSI_BLUE}{code}{ANSI_RESET}\n\ -\n{ANSI_GRAY}Device codes are a common phishing target. Never share this code.{ANSI_RESET}\n", - ); +\n{ANSI_GRAY}Continue only if you started this login in Codex. If a website or another person gave you this code, cancel.{ANSI_RESET}\n", + ) +} + +fn print_device_code_prompt(verification_url: &str, code: &str) { + let prompt = device_code_prompt(verification_url, code); + println!("{prompt}"); } pub async fn request_device_code(opts: &ServerOptions) -> std::io::Result { @@ -230,3 +235,7 @@ pub async fn run_device_code_login(opts: ServerOptions) -> std::io::Result<()> { print_device_code_prompt(&device_code.verification_url, &device_code.user_code); complete_device_code_login(opts, device_code).await } + +#[cfg(test)] +#[path = "device_code_auth_tests.rs"] +mod tests; diff --git a/codex-rs/login/src/device_code_auth_tests.rs b/codex-rs/login/src/device_code_auth_tests.rs new file mode 100644 index 0000000000..ba6071ba88 --- /dev/null +++ b/codex-rs/login/src/device_code_auth_tests.rs @@ -0,0 +1,10 @@ +use super::*; + +#[test] +fn device_code_prompt_renders_phishing_warning() { + let prompt = device_code_prompt("https://example.com/device", "ABCD-EFGH"); + + assert!(prompt.contains( + "\x1b[90mContinue only if you started this login in Codex. If a website or another person gave you this code, cancel.\x1b[0m" + )); +} diff --git a/codex-rs/tui/src/onboarding/auth/headless_chatgpt_login.rs b/codex-rs/tui/src/onboarding/auth/headless_chatgpt_login.rs index bdaac75ec3..2f7f2992d7 100644 --- a/codex-rs/tui/src/onboarding/auth/headless_chatgpt_login.rs +++ b/codex-rs/tui/src/onboarding/auth/headless_chatgpt_login.rs @@ -126,7 +126,7 @@ pub(super) fn render_device_code_login( ])); lines.push("".into()); lines.push( - " Device codes are a common phishing target. Never share this code." + " Continue only if you started this login in Codex. If a website or another person gave you this code, cancel." .dim() .into(), );