java.net.URL.equals() performs a DNS lookup and considers two URLs equal if their IP addresses match — even when the domains are completely different. This can bypass whitelist checks and lead to SSRF or DNS rebinding attacks.
Oracle explicitly documents this behavior:
Two hosts are considered equivalent if both host names can be resolved into the same IP addresses.
// Dangerous! DNS resolution + IP comparison
URL trusted = new URL("http://intranet.corp/");
URL userInput = new URL("http://evil.com/");
// If evil.com resolves to the same IP as intranet.corp
if (trusted.equals(userInput)) { // returns true!
openConnection(userInput); // request goes to evil.com
}
// If both domains resolve to the same IP:
url.equals(other) // true — DNS resolution, unsafe
url.toExternalForm().equals(other) // false — string comparison, safe
URI.create(url).equals(otherURI) // false — no DNS, safe
url.getHost().equals(other.getHost()) // false — hostname only, safe
// Dangerous patterns with java.net.URL
URL.equals(other)
HashSet<URL>.contains(url)
HashMap<URL, ?>.get(url)
// Safe alternatives
url.toString().equals(other.toString())
HashSet<String>.contains(url.toString())
Map<String, ?> with url.getHost() as key