The vulnerability, DNS Cache Poisoning, is caused by two main factors in Netty's DNS resolver: the use of a predictable pseudo-random number generator (PRNG) for DNS query IDs and a default static source port for DNS queries. The combination significantly reduces the entropy needed to protect against DNS spoofing attacks.
The analysis of the provided patch commit a034a9e653ae5a391a8b2a9cbe06fd8928794e8f confirms this. The patch replaces all usages of java.util.concurrent.ThreadLocalRandom (aliased via PlatformDependent.threadLocalRandom()) with the cryptographically secure java.security.SecureRandom.
The primary vulnerable function is io.netty.resolver.dns.DnsQueryIdRange.pushId. Before the patch, this function used ThreadLocalRandom to shuffle returned DNS query IDs back into the available pool. Because ThreadLocalRandom is a linear congruential generator, its output is predictable if an attacker can observe a few generated numbers. This allows an attacker to predict future query IDs.
Additionally, the io.netty.resolver.dns.DnsQueryIdSpace.nextId function used the same weak PRNG to make decisions about allocating new ID buckets, further contributing to the predictability. By combining the predicted ID with the static source port (a behavior noted in the patch's comment changes to DnsNameResolverChannelStrategy), an attacker can craft a malicious DNS response that the resolver will accept, poisoning the DNS cache.