mirror of
https://github.com/Athou/commafeed.git
synced 2026-09-22 12:04:16 +00:00
more SSRF protection regarding IPv6
This commit is contained in:
@@ -7,6 +7,8 @@ import com.google.common.net.HttpHeaders;
|
||||
import inet.ipaddr.IPAddress;
|
||||
import inet.ipaddr.IPAddressNetwork;
|
||||
import inet.ipaddr.IPAddressString;
|
||||
import inet.ipaddr.ipv4.IPv4Address;
|
||||
import inet.ipaddr.ipv6.IPv6Address;
|
||||
|
||||
import jakarta.inject.Singleton;
|
||||
|
||||
@@ -137,8 +139,38 @@ public class HttpClientFactory {
|
||||
}
|
||||
|
||||
private static boolean isLocalAddress(InetAddress address) {
|
||||
IPAddress ip = new IPAddressNetwork.IPAddressGenerator().from(address);
|
||||
return ip.isLocal() || ip.isLoopback() || ip.isMulticast() || CGNAT_RANGE.contains(ip);
|
||||
return isLocalAddress(new IPAddressNetwork.IPAddressGenerator().from(address));
|
||||
}
|
||||
|
||||
private static boolean isLocalAddress(IPAddress ip) {
|
||||
if (ip.isLocal() || ip.isLoopback() || ip.isMulticast() || CGNAT_RANGE.contains(ip)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ip.isIPv6()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// IPv6 transition mechanisms embed an IPv4 address that must be validated too, otherwise
|
||||
// they could be used to smuggle a blocked IPv4 target past the IPv6-only checks above
|
||||
IPv6Address ipv6 = ip.toIPv6();
|
||||
if (ipv6.isIPv4Mapped() || ipv6.isIPv4Compatible() || ipv6.isWellKnownIPv4Translatable()) {
|
||||
// IPv4-mapped (::ffff:x.x.x.x), IPv4-compatible (::x.x.x.x) and NAT64
|
||||
// (64:ff9b::/96, RFC 6052) addresses all embed the IPv4 address in the lowest 32 bits
|
||||
return isLocalAddress(ipv6.getEmbeddedIPv4Address());
|
||||
}
|
||||
if (ipv6.is6To4()) {
|
||||
// 6to4 (2002::/16, RFC 3056) embeds the IPv4 address in bits 16-47
|
||||
return isLocalAddress(ipv6.get6To4IPv4Address());
|
||||
}
|
||||
if (ipv6.isTeredo()) {
|
||||
// Teredo (2001::/32, RFC 4380) embeds the IPv4 address in the lowest 32 bits,
|
||||
// obfuscated with a bitwise complement
|
||||
IPv4Address obfuscated = ipv6.getEmbeddedIPv4Address();
|
||||
return isLocalAddress(new IPv4Address(~obfuscated.intValue()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private record BlockLocalAddressesDnsResolver(DnsResolver delegate) implements DnsResolver {
|
||||
|
||||
Reference in New Issue
Block a user