Popular npm library netmask has a critical networking vulnerability.
netmask is frequently used by hundreds of thousands of applications to parse IPv4 addresses and CIDR blocks or compare them.
The component gets over 3 million weekly downloads, and as of today, has scored over 238 million total downloads over its lifetime. Further, about 278,000 GitHub repositories depend on netmask.
The bug present in the library means when parsing an IP address with a leading zero, netmask sees a different IP due to improper validations in place.
Leading zero changes the IP address
The vulnerability, tracked as CVE-2021-28918, concerns how netmask handles mixed-format IP addresses, or more specifically when a decimal IPv4 address contains a leading zero.
An IP address can be represented in a variety of formats, including hexadecimal and integer, although most commonly seen IPv4 addresses are expressed in decimal format.
For example, BleepingComputer's IPv4 address represented in decimal format is 22.214.171.124, but the same can be expressed in the octal format as, 0150.0024.0073.0321.
Say you are given an IP address in decimal format, 127.0.0.1, which is widely understood as the local loopback address or localhost.
If you were to prefix a 0 to it, should an application still parse 0127.0.0.1 as 127.0.0.1 or something else?
Try this in your web browser. In tests by BleepingComputer, 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 in fact changes to its decimal equivalent of 126.96.36.199, which is how most applications are supposed to handle such ambiguous IP addresses.
Of particular note is the fact, 127.0.0.1 is not a public IP address but a loopback address, however, its ambiguous representation changes it to a public IP address leading to a different host altogether.
But, in the case of the npm library netmask, any leading zeros would simply be stripped and discarded.
According to IETF's original specification, parts of an IPv4 address can be interpreted as octal if prefixed with a "0."
"But netmask ignores this. It will always consider parts as being decimal, which means that if you try and validate that an IP belongs in a range, it will be wrong for octal-based representations of IPv4 addresses," Sahler and Viale told BleepingComputer in an email interview.
SSRF and blocklist bypass to Remote File Inclusion
At first glance this bug may seem like no big deal but should an attacker be able to influence the IP address input being parsed by the application, the bug can give rise to various vulnerabilities, from Server-Side Request Forgery (SSRF) bypasses to Remote File Inclusion (RFI).
The researchers shared various examples with BleepingComputer demonstrating the same.
"Someone is running a node server to sanitise an inbound request or query parameter expected to be a URI used for further connection, fetching resources, something like that."
"This could be useful for SSRF, for example, to force a server to connect to 127.0.0.1 by passing in 0177.0.0.01. 177 is base-8 for 127 in decimal," Kaoudis told BleepingComputer.
"A good example is a system that exposes webhooks and validates the user URLs through a netmask check is vulnerable to SSRF," Viale also added.
Whereas, this bug can also be exploited for Remote File Inclusion (RFI) should an attacker craft an IP address that looks private to netmask, because of the way netmask converts all IPv4 parts (octets) to decimal format, but is evaluated as public by other components, Kaoudis explained to BleepingComputer.
In 2018, the popular software project curl was also found to have an identical flaw where it treated parse octal IPv4 addresses as decimal:
In tests by BleepingComputer, running "curl -v 0188.8.131.52" has curl connecting to 184.108.40.206 as opposed to the loopback address 127.0.0.1.
Back then, an ethical hacker Grégoire had also shed light on how such a flaw could be exploited to bypass IP-based Access Control Lists (ACLs).
"I often use these conversions in order to bypass anti-SSRF blacklists," said ethical hacker Nicolas Grégoire.
Various network infrastructure and security products, such as Web Application Firewalls rely on netmask to filter out IPs present on blocklists and allowlists.
This also means flaws like these, if left unchecked, can lead to serious slip-ups in perimeter security controls.
Previously, Sick Codes, Jackson, and Sahler had identified a similar flaw in the private-ip package which turns out, also uses netmask as a dependency even today.
Ultimately, Jackson says, this newly discovered issue in netmask leaves thousands of projects vulnerable to the SSRF bypass.
"Netmask has millions of downloads weekly, making the impact quite heavy. This is a huge software supply chain vulnerability."
"In retrospect, our private-ip CVE hit a 9.8 in criticality and only had around 175,000 downloads weekly," Jackson told BleepingComputer.
The researcher's main concern is that many projects using netmask for IP parsing may be under the mistaken assumption that they are protected against SSRF.
Fixed version released on npm
Following the researchers' responsible reporting of the vulnerability, netmask developer Olivier Poitrey pushed out a series of fixes [1, 2, 3] for the bug to GitHub, along with test cases validating that IPv4 octets with 0-prefixes are treated as octal and not decimal numbers.
The fix for CVE-2021-28918 has been released in version 2.0.0 of netmask on npm downloads.
When asked for comment on the critical nature of this vulnerability, the developer told BleepingComputer that it depends on how one defines "critical."
"Depends how you define critical and how you use this lib. It’s not a buffer overflow or remote execution kind of bug."
"I can not DoS your app but weaken your ACL if it's based on IP access using this lib."
"I have yet to imagine a scenario where it could be exploited though, as most of the time ACLs are based on IPs learned from the IP stack, and those will never use the vulnerable format," Poitrey told BleepingComputer.
Users of the netmask npm library are encouraged to upgrade to the fixed version 2.0.0.
Although BleepingComputer has not yet come across information indicating if the Perl component Net::Netmask also suffers from this flaw, developers using the Perl version are advised to ensure their applications sanitize and normalize IP addresses prior to passing these as inputs to Netmask.