How Go and Rust “net” library Impacted by Sensitive IP Address Validation Vulnerability?

The frequently used “net” library in Go and Rust languages is also harmed by the mixed-format IP address validation vulnerability. The flaw has do not with how net treats IP addresses as decimal, even when they are given in a mixed (octal-decimal) format.

Therefore, applications relying on the net could be vulnerable to indeterminate Server-Side Request Forgery (SSRF) and Remote File Inclusion (RFI) vulnerabilities. Moreover, the error affected various implementations of the netmask library, depended on thousands of applications.

Later on, the Python standard library called IP address was also discovered to be vulnerable to the flaw.

Well-known Zero changes the IP address

This week, at DEF CON, security investigators Cheng Xu, Victor Viale, Sick Codes, Nick Sahler, Kelly Kaoudis, open note, and John Jackson have revealed an error in the net module of Go and Rust languages.

The vulnerability, tracked by CVE-2021-29922 (for Rust) and CVE-2021-29923 (for Golang) issues on how net handles mixed-format IP addresses, or more specifically when a decimal IPv4 address includes a leading zero.

A simple search for “import net” on GitHub announced over 4 million files for Go alone relying on the net library.

An IP address can be represented in several formats, including hexadecimal and integer, however, most commonly seen IPv4 addresses are expressed in the decimal format.

For example, our IPv4 addresses represented in decimal format is 104.20.59.209, but the same can be expressed in the octal format as, 0150.0024.0073.0321.

Like you are given an IP address in decimal format, 127.0.0.1, which is most widely understood as the local loopback address or localhost.

If one wants to prefix a 0 to it, should an application still parse 0127.0.0.1 as 127.0.0.1 or something else?  

You should try this in your web browser. In a test by our experts, typing 0127.0.0.1/ in Chrome’s address bar has the browser treating it as an IP in octal format.

On pressing enter or return, the IP changes to its decimal equivalent of 87.0.0.1, which is how most applications are supposed to manage such uncertain IP addresses.

On a particular note is a fact, 127.0.0.1 is not a public IP address but a loopback address, however, its uncertain representation changes it to a public IP address leading to a different host altogether.

In the cases of the net library, any leading zeros would simply be stripped and discarded.

Therefore, if a developer was using net to validate if an IP address belongs to a certain range (e.g. parsing a list of IPs against an access control list (ACL)), the result may come across for octal-based representations of IPv4 addresses.

How-Rust-“net”-library-Impacted-by-Sensitive-IP-Address-Validation-Vulnerability-image2

Multiple Applications and Languages Harmed

Go and Rust is not the only languages to be harmed by this flaw.

This mixed-format IP address validation flaw had previously harmed Python’s IP address library (CVE-2021-29921), netmask implementations (CVE-2021-28918, CVE-2021-29418), and similar libraries.

In most of the cases, the flaw has been rated as having a High or sensitive severity:

How-Rust-“net”-library-Impacted-by-Sensitive-IP-Address-Validation-Vulnerability-image3

As per the project maintainers, Golang’s net module would have patch (1,2) issues in (beta) version 1.17.

“All in all, since they were standard library changes that would harm all the projects written in the language themselves, they required a lot of testing or for the patches to be made redundant,” Sick Codes told our experts in an email interview.

Rust language users should be using a version of 1.53.0 or above that includes the mitigation for this vulnerability.   

Leave a Reply