Zero-day vulnerability in Python versions 3.8.0 to 3.8.3 causes hash collisions and lead to DoS

0

CVE-2020-14422 Zero-day vulnerability in Python versions 3.8.0, 3.8.1, 3.8.2, and 3.8.3 could cause IPv4 and IPv6 hash collisions, which in turn can lead to Denial of Service

Security researchers have discovered a Zero-day in Python version 3.8.0, 3.8.1, 3.8.2, and 3.8.3  which causes hash collisions in IPv4Interface and IPv6Interface and could lead to a denial of service (DoS). The vulnerability has been assigned an identifier, CVE-2020-14422, and has a medium vulnerability score of 5/10 by NVD.

The vulnerability in Python, the popular programming language could be exploited by potential hackers to allow the deployment of denial of service (DoS) attacks. According to the Python Bug Report, the vulnerability is stated as trivial and resolved.

In the ipaddress library there exists two classes IPv4Interface, and IPv6Interface. These classes' hash functions will always return 32 and 64 respectively. If IPv4Interface or IPv6Interface objects then are put in a dictionary, on for example a server storing IPs, this will cause hash collisions, which in turn can lead to DOS.

The Python zero-day vulnerability exists in the way two classes IPv4Interface, and IPv6Interface interact. These classes’ hash functions will always return 32 and 64 respectively. But Lib/ipaddress.py in Python through 3.8.3 improperly computes hash values in the IPv4Interface and IPv6Interface classes, which might allow a remote attacker to cause a denial of service if an application is affected by the performance of a dictionary containing IPv4Interface or IPv6Interface objects, and this attacker can cause many dictionary entries to be created.

Python Bug Report page says that the issue can be fixed by fixing a single line entry in 1421 and 2095.

The root of this is on line 1421 and 2095. On both lines, self._ip and self.network.network_address will both be same, and when xor is applied they will cancel eachother out, leaving return self._prefixlen .
Since self._prefixlen is a constant, 32 and 64 respectively, this will lead to a constant hash.

The fix is trivial, on line 1421, change to:
return hash((self._ip, self._prefixlen, int(self.network.network_address)))

and on line 2095, change to:
return hash((self._ip, self._prefixlen, int(self.network.network_address)))

OpenSuse has already fixed the issue in their Linux distro and you can patch your version by visiting this page.

Share.

About Author

"The Internet is the first thing that humanity has built that humanity doesn't understand, the largest experiment in anarchy that we have ever had." Eric Schmidt

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments