diff --git a/stdlib/src/web.rs b/stdlib/src/web.rs index 3edf64c6..e9f9a11e 100644 --- a/stdlib/src/web.rs +++ b/stdlib/src/web.rs @@ -17,7 +17,7 @@ fn is_safe_ip(ip: &IpAddr) -> bool { && !ipv4.is_unspecified() } IpAddr::V6(ipv6) => { - if let Some(ipv4) = ipv6.to_ipv4() { + if let Some(ipv4) = ipv6.to_ipv4_mapped() { // Check IPv4-mapped IPv6 return is_safe_ip(&IpAddr::V4(ipv4)); } @@ -597,3 +597,100 @@ impl StdlibRegistry { ); } } + +#[cfg(test)] +mod tests { + use super::*; + use std::net::IpAddr; + + #[test] + fn test_safe_ipv4() { + let ip: IpAddr = "8.8.8.8".parse().unwrap(); + assert!(is_safe_ip(&ip)); + + let ip: IpAddr = "1.1.1.1".parse().unwrap(); + assert!(is_safe_ip(&ip)); + } + + #[test] + fn test_unsafe_ipv4() { + // Private + let ip: IpAddr = "10.0.0.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + let ip: IpAddr = "172.16.0.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + let ip: IpAddr = "192.168.1.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Loopback + let ip: IpAddr = "127.0.0.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Link-local + let ip: IpAddr = "169.254.0.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Broadcast + let ip: IpAddr = "255.255.255.255".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Documentation + let ip: IpAddr = "192.0.2.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + let ip: IpAddr = "198.51.100.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + let ip: IpAddr = "203.0.113.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Unspecified + let ip: IpAddr = "0.0.0.0".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + } + + #[test] + fn test_safe_ipv6() { + let ip: IpAddr = "2001:4860:4860::8888".parse().unwrap(); + assert!(is_safe_ip(&ip)); + } + + #[test] + fn test_unsafe_ipv6() { + // Loopback + let ip: IpAddr = "::1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Unspecified + let ip: IpAddr = "::".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Unique Local Address + let ip: IpAddr = "fc00::1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + let ip: IpAddr = "fd00::1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Link Local Address + let ip: IpAddr = "fe80::1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + } + + #[test] + fn test_ipv4_mapped_ipv6() { + // Mapped loopback (127.0.0.1) + let ip: IpAddr = "::ffff:127.0.0.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Mapped private (10.0.0.1) + let ip: IpAddr = "::ffff:10.0.0.1".parse().unwrap(); + assert!(!is_safe_ip(&ip)); + + // Mapped public (8.8.8.8) + let ip: IpAddr = "::ffff:8.8.8.8".parse().unwrap(); + assert!(is_safe_ip(&ip)); + } +}