mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-08-30 23:28:29 +00:00
Fix Host/IP resolving (#7162)
IPv4 addresses can also be in decimal or hex formats. These were not checked during the Global IP check, and could bypass it. We now convert everything to the right format before running this check and it will catch these formats. Also updated the `is_global()` function to match Rust's still unstable version. And updated the Image Magic checks to be more precise and filter out any possible broken or invalid formats. While at it, also added several checks to ensure these special formatted IPv4 addresses are still blocked and punycode domains are also correctly resolved. Signed-off-by: BlackDex <black.dex@gmail.com>
This commit is contained in:
+17
-7
@@ -818,14 +818,18 @@ pub fn is_global_hardcoded(ip: std::net::IpAddr) -> bool {
|
||||
std::net::IpAddr::V4(ip) => {
|
||||
!(ip.octets()[0] == 0 // "This network"
|
||||
|| ip.is_private()
|
||||
|| (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) //ip.is_shared()
|
||||
|| (ip.octets()[0] == 100 && (ip.octets()[1] & 0b1100_0000 == 0b0100_0000)) // ip.is_shared()
|
||||
|| ip.is_loopback()
|
||||
|| ip.is_link_local()
|
||||
// addresses reserved for future protocols (`192.0.0.0/24`)
|
||||
||(ip.octets()[0] == 192 && ip.octets()[1] == 0 && ip.octets()[2] == 0)
|
||||
// .9 and .10 are documented as globally reachable so they're excluded
|
||||
|| (
|
||||
ip.octets()[0] == 192 && ip.octets()[1] == 0 && ip.octets()[2] == 0
|
||||
&& ip.octets()[3] != 9 && ip.octets()[3] != 10
|
||||
)
|
||||
|| ip.is_documentation()
|
||||
|| (ip.octets()[0] == 198 && (ip.octets()[1] & 0xfe) == 18) // ip.is_benchmarking()
|
||||
|| (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) //ip.is_reserved()
|
||||
|| (ip.octets()[0] & 240 == 240 && !ip.is_broadcast()) // ip.is_reserved()
|
||||
|| ip.is_broadcast())
|
||||
}
|
||||
std::net::IpAddr::V6(ip) => {
|
||||
@@ -849,11 +853,17 @@ pub fn is_global_hardcoded(ip: std::net::IpAddr) -> bool {
|
||||
// AS112-v6 (`2001:4:112::/48`)
|
||||
|| matches!(ip.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
|
||||
// ORCHIDv2 (`2001:20::/28`)
|
||||
|| matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if (0x20..=0x2F).contains(&b))
|
||||
// Drone Remote ID Protocol Entity Tags (DETs) Prefix (`2001:30::/28`)`
|
||||
|| matches!(ip.segments(), [0x2001, b, _, _, _, _, _, _] if (0x20..=0x3F).contains(&b))
|
||||
))
|
||||
|| ((ip.segments()[0] == 0x2001) && (ip.segments()[1] == 0xdb8)) // ip.is_documentation()
|
||||
|| ((ip.segments()[0] & 0xfe00) == 0xfc00) //ip.is_unique_local()
|
||||
|| ((ip.segments()[0] & 0xffc0) == 0xfe80)) //ip.is_unicast_link_local()
|
||||
// 6to4 (`2002::/16`) – it's not explicitly documented as globally reachable,
|
||||
// IANA says N/A.
|
||||
|| matches!(ip.segments(), [0x2002, _, _, _, _, _, _, _])
|
||||
|| matches!(ip.segments(), [0x2001, 0xdb8, ..] | [0x3fff, 0..=0x0fff, ..]) // ip.is_documentation()
|
||||
// Segment Routing (SRv6) SIDs (`5f00::/16`)
|
||||
|| matches!(ip.segments(), [0x5f00, ..])
|
||||
|| ip.is_unique_local()
|
||||
|| ip.is_unicast_link_local())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user