The vulnerability exists in the ipRestriction middleware, specifically within the logic created by the buildMatcher function. The root cause is the failure to canonicalize IPv4-mapped IPv6 addresses (e.g., ::ffff:192.168.1.1) to their standard IPv4 representation before matching them against user-defined IP rules.
Before the patch, the matching logic would treat an address like ::ffff:127.0.0.1 as a true IPv6 address because it contains colons. Consequently, it would not be compared against IPv4 rules in the allowList or denyList. For example, a CIDR rule check included if (isIPv4 !== remote.isIPv4) { continue }, which would cause an IPv4 rule to be skipped for an IPv4-mapped IPv6 address, allowing the request to bypass the restriction.
The patch addresses this by:
- Introducing helper functions
isIPv4MappedIPv6 and convertIPv4MappedIPv6ToIPv4 to detect and convert these special addresses.
- Modifying the
buildMatcher function to create a new matching function that canonicalizes the incoming remote IP address. If it's an IPv4-mapped IPv6 address, it's converted to its IPv4 equivalent before being checked against the rules.
- For static IP rules, the patch now adds both the plain IPv4 address and its IPv4-mapped (
::ffff:) equivalent to the set of rules to ensure a match regardless of how the address is represented.
The vulnerable functions are ipRestriction (the public API) and the internal buildMatcher function, which contains the flawed logic for generating the IP address matcher. An attacker could exploit this by sending requests from an IP address that is on a deny list, but the request's source IP is represented as an IPv4-mapped IPv6 address, bypassing the check.