{"record":{"id":"9a18b99588939981","repo":"Hmbown/CodeWhale","slug":"mcp-http-url-must-not-contain-credentials-use-configured","errorCode":null,"errorMessage":"MCP HTTP URL must not contain credentials; use configured headers","messagePattern":"MCP HTTP URL must not contain credentials; use configured headers","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/http_client.rs","lineNumber":49,"sourceCode":"    request_builder: reqwest::Client,\n    clients: Arc<Mutex<HashMap<String, reqwest::Client>>>,\n}\n\nimpl McpHttpClient {\n    pub(super) fn new(\n        url: &str,\n        runtime_added: bool,\n        reviewed_plugin: bool,\n        allow_private_network: bool,\n        network_policy: Option<&NetworkPolicyDecider>,\n        connect_timeout: Duration,\n        read_timeout: Duration,\n    ) -> Result<Self> {\n        let url = Url::parse(url).context(\"invalid MCP HTTP endpoint\")?;\n        validate_url(&url)?;\n        validate_network_policy(&url, network_policy)?;\n        if (runtime_added || reviewed_plugin) && url_has_credentials(&url) {\n            bail!(\"MCP HTTP URL must not contain credentials; use configured headers\");\n        }\n        Ok(Self {\n            origin: url.origin().ascii_serialization(),\n            operator_configured: !runtime_added,\n            private_origin_allowed: !runtime_added\n                && (allow_private_network || explicit_local_target(&url)),\n            #[cfg(test)]\n            dns_answers: Arc::new(Mutex::new(None)),\n            reviewed_plugin,\n            network_policy: network_policy.cloned(),\n            connect_timeout,\n            read_timeout,\n            default_headers: header::HeaderMap::new(),\n            request_builder: guarded_reqwest_client_builder().build()?,\n            clients: Arc::new(Mutex::new(HashMap::new())),\n        })\n    }\n","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/http_client.rs#L31-L67","documentation":"The MCP HTTP client constructor rejects endpoint URLs that embed credentials (user:password@) when the endpoint was added at runtime or comes from a reviewed plugin. Credentials in URLs leak into logs and proxies; the library requires them to be sent as configured headers instead.","triggerScenarios":"Calling McpHttpClient::new with a URL like https://user:pass@example.com/mcp while runtime_added==true or reviewed_plugin==true, so url_has_credentials(&url) is true.","commonSituations":"Pasting a provider URL that includes an API key as basic-auth userinfo; a plugin manifest carrying credentials in its endpoint URL; migrating a curl-style URL (which commonly embeds auth) into an MCP config.","solutions":["Strip the userinfo from the URL and supply credentials via the headers argument instead","If you are the operator (not runtime-added/reviewed-plugin), configure the endpoint through the operator config path where credentials in URL are permitted","Use an Authorization header in configured headers, e.g. Authorization: Basic <base64> or Bearer <token>"],"exampleFix":"// before\nMcpHttpClient::new(\"https://user:secret@example.com/mcp\", true, false, ...)\n// after\nlet headers = [(\"Authorization\", format!(\"Basic {}\", base64(\"user:secret\")))];\nMcpHttpClient::new(\"https://example.com/mcp\", true, false, ...).with_headers(headers)","handlingStrategy":"validation","validationCode":"fn url_has_credentials(url: &Url) -> bool {\n    !url.username().is_empty() || url.password().is_some()\n}\nlet parsed = Url::parse(endpoint)?;\nif runtime_added && url_has_credentials(&parsed) {\n    // move credentials to headers before constructing the client\n}","typeGuard":"fn is_credential_free_http_url(s: &str) -> Option<Url> {\n    let u = Url::parse(s).ok()?;\n    (matches!(u.scheme(), \"http\" | \"https\")\n        && !u.username().is_empty() == false\n        && u.password().is_none()).then_some(u)\n}","tryCatchPattern":null,"preventionTips":["Store API credentials in header configuration, never in endpoint URLs","Scan MCP config files for 'user:pass@' patterns during review","Use a credential manager and inject Authorization headers at connect time"],"tags":["mcp","http","url","credentials","security"],"backgroundTag":"missing-credentials","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}