Hmbown/CodeWhale · error · anyhow::Error
The Codewhale service returned an untrusted verification ori
Error message
The Codewhale service returned an untrusted verification origin
What it means
When the account API base is the canonical https://api.codewhale.net:443, the CLI requires the login verification URL to be exactly https on app.codewhale.net with the default port 443. This bail fires when any of those three origin properties drift, because a different origin could be an attacker-controlled page receiving the user code.
Source
Thrown at crates/cli/src/cloud.rs:817
})?;
if !url.username().is_empty() || url.password().is_some() || url.fragment().is_some() {
bail!("The Codewhale service returned an unsafe verification URL");
}
if url.path() != "/cli/authorize" {
bail!("The Codewhale service returned an unsafe verification URL");
}
let api = Url::parse(api_base).context("invalid Codewhale account API base URL")?;
let canonical_api = api.scheme() == "https"
&& api.host_str() == Some("api.codewhale.net")
&& api.port_or_known_default() == Some(443);
let loopback_api = api.host_str().is_some_and(is_loopback_host);
if canonical_api {
if url.scheme() != "https"
|| !host.eq_ignore_ascii_case("app.codewhale.net")
|| url.port_or_known_default() != Some(443)
{
bail!("The Codewhale service returned an untrusted verification origin");
}
} else if loopback_api {
if !matches!(url.scheme(), "http" | "https") || !is_loopback_host(host) {
bail!("The Codewhale service returned an untrusted verification origin");
}
} else {
bail!(
"Browser login is only enabled for the canonical Codewhale account API or a loopback test API"
);
}
let query = url.query_pairs().collect::<Vec<_>>();
if complete {
if query.len() != 1 || query[0].0 != "user_code" || query[0].1 != user_code {
bail!("The Codewhale service returned an unsafe verification URL");
}
} else if !query.is_empty() {
bail!("The Codewhale service returned an unsafe verification URL");View on GitHub (pinned to 0c42157ee5)
Solutions
- Confirm --api-base is the real canonical API and not a local override masquerading as it
- Fix the service/config so verification URLs are exactly https://app.codewhale.net/cli/authorize[?user_code=...]
- Drop any explicit :443 or non-default port from the returned URL (the check requires port_or_known_default() == 443)
- Update CLI and service to matching releases if the frontend host recently changed
Example fix
// before verification_url: "https://app.codewhale.net:8443/cli/authorize" // after verification_url: "https://app.codewhale.net/cli/authorize"
Defensive patterns
Strategy: validation
Validate before calling
fn is_trusted_origin(raw: &str, api_base: &str) -> bool {
let (Ok(url), Ok(api)) = (url::Url::parse(raw), url::Url::parse(api_base)) else { return false };
let canonical = api.scheme() == "https"
&& api.host_str() == Some("api.codewhale.net")
&& api.port_or_known_default() == Some(443);
canonical && url.scheme() == "https"
&& url.host_str().is_some_and(|h| h.eq_ignore_ascii_case("app.codewhale.net"))
&& url.port_or_known_default() == Some(443)
} Try / catch
if !is_trusted_origin(&verification_url, api_base) {
anyhow::bail!("refusing to open untrusted origin: {verification_url}");
} Prevention
- Compare origins exactly (scheme+host+default port), never substring-match hosts
- Keep the canonical frontend host in one config constant shared by client and service
- Add a test that a malicious look-alike host (e.g. app.codewhale.net.evil.com) is rejected
When it happens
Trigger: --api-base is https://api.codewhale.net (or https://api.codewhale.net:443) and the returned verification URL is http://, a host other than app.codewhale.net (even a subdomain like eu.app.codewhale.net), or carries a non-default port such as :8443.
Common situations: A local mock or proxy that answers on api.codewhale.net while returning localhost URLs; a service-side config pointing the frontend at a vanity domain or staging host; a port-forward that adds an explicit port to the URL.
Related errors
- Codewhale account login timed out; run `codewhale account lo
- The Codewhale service returned an unsafe verification URL
- The Codewhale service returned an invalid user code
- The Codewhale service returned an invalid device authorizati
- Codewhale account API base URL must not contain credentials
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/954592712b0afa4c.
Report an issue: GitHub.