{"record":{"id":"c6702ace9f358805","repo":"tinyhumansai/openhuman","slug":"dns-rebinding-blocked-host-resolved-to-privat","errorCode":null,"errorMessage":"DNS rebinding blocked: '{host}' resolved to private/local address {ip_str}","messagePattern":"DNS rebinding blocked: '(.+?)' resolved to private/local address (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/tools/impl/network/url_guard.rs","lineNumber":140,"sourceCode":"    if host.parse::<std::net::IpAddr>().is_ok() {\n        return Ok(url);\n    }\n\n    let port = extract_port(&url)?;\n    log::debug!(\"[url_guard] resolving DNS for host={host} port={port}\");\n    let addrs = resolver(host.clone(), port).await?;\n\n    if addrs.is_empty() {\n        anyhow::bail!(\"DNS resolution returned no addresses for '{host}'\");\n    }\n\n    log::debug!(\"[url_guard] DNS resolved host={host} addrs={}\", addrs.len());\n\n    for addr in &addrs {\n        let ip_str = addr.to_string();\n        if is_private_or_local_host(&ip_str) {\n            log::debug!(\"[url_guard] DNS rebinding blocked host={host} resolved_ip={ip_str}\");\n            anyhow::bail!(\n                \"DNS rebinding blocked: '{host}' resolved to private/local address {ip_str}\"\n            );\n        }\n    }\n\n    Ok(url)\n}\n\nasync fn resolve_host_ips(host: String, port: u16) -> anyhow::Result<Vec<IpAddr>> {\n    let log_host = host.clone();\n    tokio::task::spawn_blocking(move || {\n        (host.as_str(), port)\n            .to_socket_addrs()\n            .map_err(|e| {\n                log::debug!(\"[url_guard] DNS resolution failed host={host} port={port} error={e}\");\n                anyhow::anyhow!(\"DNS resolution failed for '{host}': {e}\")\n            })\n            .map(|iter| iter.map(|addr| addr.ip()).collect())","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/tools/impl/network/url_guard.rs#L122-L158","documentation":"DNS rebinding defense: the hostname passed the textual checks, but at least one resolved IP is private or local, meaning the domain could be a rebinding front for internal infrastructure; every such resolution causes the whole request to be blocked.","triggerScenarios":"Thrown at src/openhuman/tools/impl/network/url_guard.rs:140 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Use a host whose DNS records point only at public addresses","If this is your own domain, remove private/local A or AAAA records from it","Do not attempt to reach internal services through http_request"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}