forked from mirrors/kingfisher
updated in response to ossf scorecard
This commit is contained in:
parent
e0a403607f
commit
93cd6e940c
3 changed files with 29 additions and 13 deletions
|
|
@ -528,6 +528,13 @@ pub async fn check_url_resolvable(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Backwards-compatible wrapper: checks URL resolvability with SSRF protection
|
||||
/// enabled (i.e., `allow_internal_ips = false`).
|
||||
#[deprecated(since = "0.1.0", note = "use check_url_resolvable(url, allow_internal_ips) instead")]
|
||||
pub async fn check_url_resolvable_safe(url: &Url) -> Result<(), Box<dyn std::error::Error>> {
|
||||
check_url_resolvable(url, false).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -59,9 +59,11 @@ pub use utils::{find_closest_variable, process_captures};
|
|||
pub use validation_body::{as_str, clone_as_string, from_string, ValidationResponseBody};
|
||||
|
||||
#[cfg(feature = "validation-http")]
|
||||
#[allow(deprecated)]
|
||||
pub use http_validation::{
|
||||
build_request_builder, check_url_resolvable, generate_http_cache_key_parts, is_ssrf_safe_ip,
|
||||
parse_http_method, process_headers, retry_multipart_request, retry_request, validate_response,
|
||||
build_request_builder, check_url_resolvable, check_url_resolvable_safe,
|
||||
generate_http_cache_key_parts, is_ssrf_safe_ip, parse_http_method, process_headers,
|
||||
retry_multipart_request, retry_request, validate_response,
|
||||
};
|
||||
|
||||
#[cfg(feature = "validation-aws")]
|
||||
|
|
|
|||
|
|
@ -153,20 +153,27 @@ pub(crate) fn ssrf_safe_redirect_policy() -> reqwest::redirect::Policy {
|
|||
} else {
|
||||
// Hostname: resolve synchronously and check all resolved IPs.
|
||||
let port = url.port().unwrap_or(if url.scheme() == "https" { 443 } else { 80 });
|
||||
if let Ok(addrs) = std::net::ToSocketAddrs::to_socket_addrs(&(host, port as u16)) {
|
||||
for addr in addrs {
|
||||
if !kingfisher_scanner::validation::is_ssrf_safe_ip(&addr.ip()) {
|
||||
return attempt.error(format!(
|
||||
"SSRF protection: redirect to '{}' resolves to non-public IP {} — blocked",
|
||||
host,
|
||||
addr.ip()
|
||||
));
|
||||
match std::net::ToSocketAddrs::to_socket_addrs(&(host, port as u16)) {
|
||||
Ok(addrs) => {
|
||||
for addr in addrs {
|
||||
if !kingfisher_scanner::validation::is_ssrf_safe_ip(&addr.ip()) {
|
||||
return attempt.error(format!(
|
||||
"SSRF protection: redirect to '{}' resolves to non-public IP {} — blocked",
|
||||
host,
|
||||
addr.ip()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
// Fail closed: if we cannot resolve the hostname, we
|
||||
// cannot guarantee the redirect target is SSRF-safe.
|
||||
return attempt.error(format!(
|
||||
"SSRF protection: cannot resolve redirect host '{}' ({}) — blocked",
|
||||
host, e
|
||||
));
|
||||
}
|
||||
}
|
||||
// If DNS resolution fails, allow the redirect — reqwest will
|
||||
// fail on connect anyway, and we don't want to silently block
|
||||
// valid hostnames that are transiently unresolvable.
|
||||
}
|
||||
}
|
||||
attempt.follow()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue