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

  1. Confirm --api-base is the real canonical API and not a local override masquerading as it
  2. Fix the service/config so verification URLs are exactly https://app.codewhale.net/cli/authorize[?user_code=...]
  3. Drop any explicit :443 or non-default port from the returned URL (the check requires port_or_known_default() == 443)
  4. 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

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


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/954592712b0afa4c. Report an issue: GitHub.