python stdlib “ipaddress” – Improper Input Validation of octal literals in python 3.8.0 thru v3.10 results in indeterminate SSRF & RFI vulnerabilities. — “ipaddress leading zeros in IPv4 address”
3.8.0 thru v3.10
Improper input validation of octal strings in Python 3.8.0 thru v3.10 stdlib ipaddress allows unauthenticated remote attackers to perform indeterminate SSRF, RFI, and LFI attacks on many programs that rely on Python stdlib ipaddress. IP address octects are left stripped instead of evaluated as valid IP addresses. For example, an attacker submitting an IP address to a web application that relies on stdlib ipaddress, could cause SSRF via inputting octal input data; An attacker can submit exploitable IP addresses if the octet is 3 digits, with the minimum exploitable octect being 08 (Denial of Service) and the maximum exploitable octet is 099. For example, an attacker can submit 010.8.8.8, which is 220.127.116.11, yet Python ipaddress builtin will evaluate this as 10.8.8.8.
Currently unpatched – due to be addressed in next release.
Proof of Concept
Vulnerability added in python3.8
Documentated to be vulnerable in the changelog:
Stop rejecting IPv4 octets for being ambiguously octal. Leading zeros are ignored, and no longer are assumed to specify octal octets. Octets are always decimal numbers. Octets must still be no more than three digits, including leading zeroes.
#!/usr/bin/env python # Authors: sickcodes, Victor Viale # License: GPLv3+ # Reference: https://docs.python.org/3.10/library/ipaddress.html#ipaddress.IPv4Address # Leading zeroes are tolerated only for values less than 8 (as there is no ambiguity between the decimal and octal interpretations of such strings). import subprocess import ipaddress SUSPECT = '010.8.8.8' print(ipaddress.ip_network(SUSPECT, strict=True)) BAD_IP = ipaddress.ip_address(SUSPECT) print('http://'+str(BAD_IP)) print(str(subprocess.check_output("ping -W3 -v -c1 "+str(SUSPECT), shell=True, universal_newlines=True).strip())) print(str(subprocess.check_output("ping -W3 -v -c1 "+str(BAD_IP), shell=True, universal_newlines=True).strip()))
- 2019-03-20 – Issue created in https://bugs.python.org/issue36384
- 2021-03-29 – Researchers discover vulnerability
- 2021-03-29 – Vendor notified
- 2021-03-29 – CVE requested
- 2021-04-30 – CVE Assigned CVE-2021-29921 https://bugs.python.org/issue36384#msg392423
- 2021-04-30 – CVE published
Joel Croteau: https://github.com/TV4Fun
John Jackson https://www.twitter.com/johnjhacking
Christian Heimes: https://github.com/tiran
Victor Stinner: https://github.com/vstinner