ZeroHour

CVE-2026-90711

large

Fail-open IP trust spoofing in Node.js proxy-addr 1.1.0-2.0.7 (Express req.ip)

CVSS 3.1
9.1 critical
EPSS
Published
()
Modified
AI analysis

The proxy-addr Node.js module, which backs Express's req.ip and req.ips handling, incorrectly accepts a trusted proxy subnet written in IPv4-mapped IPv6 notation with an IPv4-sized prefix (e.g., ::ffff:10.0.0.0/8 instead of ::ffff:10.0.0.0/104), silently trusting every IPv4 address on the internet instead of the intended block. An unauthenticated remote attacker can exploit this by sending an arbitrary X-Forwarded-For header, which the application then trusts as the client address, defeating IP-based access controls, rate limiting, geolocation, and audit logging. The regression was introduced in proxy-addr 1.1.0 and affects all versions through 2.0.7, so any Express or other Node.js deployment that configures trust subnets in this notation is affected. The flaw is rated critical (CVSS 9.1) due to high confidentiality and integrity impact with no privileges or user interaction required. No public proof of concept exists and there is no evidence of in-the-wild exploitation, and it is not on the CISA KEV list.

What to do: Upgrade proxy-addr to 2.0.8 or later by refreshing lockfiles (npm update proxy-addr / Dependabot). Audit Express 'trust proxy' configurations for IPv4-mapped IPv6 subnets such as ::ffff:10.0.0.0/8; as an interim workaround, rewrite them with a prefix length of at least 97 (e.g., ::ffff:10.0.0.0/104) or use plain IPv4 CIDR notation. Review access-control decisions, rate-limit counters, and audit logs for suspicious or rapidly changing X-Forwarded-For values that could indicate attempted spoofing.

Affected
jshttp (open source) proxy-addr (Node.js module, used by Express for req.ip/req.ips)1.1.0 through 2.0.7 (fixed in 2.0.8)
Estimated exposure
largePlausibly thousands to tens of thousands of apps, serving potentially millions of end users — proxy-addr ships as a core dependency of Express, one of the most widely used Node.js frameworks (tens of millions of weekly npm downloads across the ecosystem), but only deployments that express trust subnets in IPv4-mapped IPv6 notation…

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

proxy-addr is a Node.js module that determines a request's client address behind trusted reverse proxies, and it backs Express req.ip and req.ips. In versions 1.1.0 through 2.0.7, a trust subnet written in IPv4-mapped IPv6 notation with an IPv4-sized prefix, such as ::ffff:10.0.0.0/8 instead of the correct ::ffff:10.0.0.0/104, is accepted without error but trusts every IPv4 address on the internet rather than the block it names. Because the socket peer then becomes trusted at hop 0, any unauthenticated client can supply an arbitrary X-Forwarded-For header and control the address the application reads, which defeats IP-based access control, rate limiting, geolocation, and audit logging. This is a fail-open regression introduced in version 1.1.0. The issue is fixed in proxy-addr 2.0.8, and users should upgrade to 2.0.8 or later. As a workaround, ensure any IPv4-mapped IPv6 trust subnet uses a prefix length of at least 97, or express the range in plain IPv4 notation.

Weakness
CWE-290, CWE-348, CWE-697
Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

In the news

No ingested article mentions this CVE yet.