{"record":{"id":"91ab84777470eaff","repo":"xai-org/grok-build","slug":"server-returned-unsupported-verification-uri-schem","errorCode":null,"errorMessage":"Server returned unsupported verification URI scheme","messagePattern":"Server returned unsupported verification URI scheme","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/auth/device_code.rs","lineNumber":525,"sourceCode":"    let claims: IdTokenClaims = match serde_json::from_slice(&payload) {\n        Ok(claims) => claims,\n        Err(_) => return (String::new(), None),\n    };\n    (claims.sub.unwrap_or_default(), claims.email)\n}\n\nfn validate_verification_uri(uri: &str) -> anyhow::Result<()> {\n    if uri.chars().any(|c| c.is_ascii_control()) {\n        anyhow::bail!(\"Server returned invalid verification URI\");\n    }\n\n    let parsed = url::Url::parse(uri)\n        .map_err(|_| anyhow::anyhow!(\"Server returned invalid verification URI\"))?;\n\n    match parsed.scheme() {\n        \"https\" => Ok(()),\n        \"http\" if matches!(parsed.host_str(), Some(\"localhost\") | Some(\"127.0.0.1\")) => Ok(()),\n        _ => anyhow::bail!(\"Server returned unsupported verification URI scheme\"),\n    }\n}\n\n#[cfg(test)]\npub(crate) mod tests {\n    use std::sync::Arc;\n\n    use super::{AuthManager, build_auth, validate_verification_uri};\n    use crate::auth::{AuthMode, GrokComConfig};\n\n    #[test]\n    fn validate_verification_uri_rejects_unsupported_scheme() {\n        let err = validate_verification_uri(\"javascript:alert(1)\").unwrap_err();\n        assert_eq!(\n            \"Server returned unsupported verification URI scheme\",\n            err.to_string()\n        );\n    }","sourceCodeStart":507,"sourceCodeEnd":543,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/auth/device_code.rs#L507-L543","documentation":"validate_verification_uri only accepts https URIs, plus http when the host is localhost or 127.0.0.1. Any other scheme (ftp, javascript, custom app schemes) or non-local http host is rejected, preventing the user from being directed to an insecure or dangerous destination.","triggerScenarios":"request_device_code (or the test validate_verification_uri_rejects_unsupported_scheme) passes a parsed URI whose scheme is not https, or an http URI whose host is not localhost/127.0.0.1 — e.g. http://example.com/device or myapp://auth.","commonSituations":"Corporate proxy or on-prem issuer serving verification over plain http on a non-localhost host; issuer using a custom deep-link scheme; typo'd or attacker-supplied URL in a tampered response.","solutions":["Ensure the authorization server advertises an https verification_uri.","If testing locally, use http://localhost:<port> or http://127.0.0.1:<port>, which are allowed.","Fix TLS on an internal issuer instead of downgrading to http.","Update the client if the official issuer's scheme policy changed."],"exampleFix":"// before\n{\"verification_uri\": \"http://auth.internal.corp/device\"}\n// after\n{\"verification_uri\": \"https://auth.internal.corp/device\"}","handlingStrategy":"validation","validationCode":"fn uri_scheme_allowed(uri: &str) -> bool {\n    match url::Url::parse(uri) {\n        Ok(u) => match u.scheme() {\n            \"https\" => true,\n            \"http\" => matches!(u.host_str(), Some(\"localhost\") | Some(\"127.0.0.1\")),\n            _ => false,\n        },\n        Err(_) => false,\n    }\n}","typeGuard":"fn as_https_or_local(uri: &str) -> Option<url::Url> {\n    let u = url::Url::parse(uri).ok()?;\n    match (u.scheme(), u.host_str()) {\n        (\"https\", _) => Some(u),\n        (\"http\", Some(\"localhost\") | Some(\"127.0.0.1\")) => Some(u),\n        _ => None,\n    }\n}","tryCatchPattern":"if let Err(e) = request_device_code(&client, &cfg).await {\n    if e.to_string().contains(\"unsupported verification URI scheme\") {\n        eprintln!(\"Issuer must serve https (or http on localhost). Fix the auth server.\");\n    }\n    return Err(e);\n}","preventionTips":["Serve the verification page over https with valid TLS on internal issuers.","Use localhost/127.0.0.1 for local testing instead of LAN hostnames over http.","Never accept custom app schemes in the verification_uri from third parties.","Review proxy rewrites that might downgrade https to http."],"tags":["oauth","device-flow","url-validation","security"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}