CVE-2026-90711: Client IP Address Spoofing and Trust Boundary Bypass via IPv4-Mapped IPv6 CIDR Parsing Flaw in proxy-addr
HERMES THREAT SCORE & ECOSYSTEM BLAST RADIUS
Target:proxy-addr (Node.js) & Downstream Frameworks (Express req.ip, Koa, NestJS, Fastify) While CVSS v3.1 rates CVE-2026-90711 at 9.1 (Critical) focusing primarily on data confidentiality and integrity impacts, Hermes emphasizes the immense ecosystem exposure and blast radius. proxy-addr accounts for over 30 million weekly npm downloads as the foundational dependency behind Express's trust-proxy subsystem. When production architectures configure trust ranges with IPv4-mapped IPv6 notation, the library inadvertently treats the entire public internet (0.0.0.0/0) as a trusted upstream proxy. Adversaries can bypass administrative IP allowlists, defeat brute-force rate limiters, forge geographic origin controls, and corrupt forensic audit logs across tens of thousands of corporate web services with single-header HTTP payloads.
HASS AGENTIC SEVERITY & PERIMETER AUTHENTICATION COLLAPSE
Target:AI Agent Ingress Gateways, Webhook Receivers & MCP Server Network Boundaries Modern enterprise AI agents and Model Context Protocol (MCP) servers frequently rely on network-level IP allowlisting (such as restricting internal tool invocation webhooks or memory sync endpoints to 127.0.0.1 or Kubernetes Pod CIDRs). By exploiting CVE-2026-90711, remote attackers spoof trusted internal origins, successfully invoking privileged agent webhook actions and bypassing perimeter access filters.
CVE-2026-90711: Client IP Address Spoofing and Trust Boundary Bypass via IPv4-Mapped IPv6 CIDR Parsing Flaw in proxy-addrVULNERABILITY
Adversary embeds covert payload instructions into retrieved external data (web pages, repositories, emails) that subvert model planning when parsed by autonomous agents.
🔍 Why is this related? (Evidence & Provenance)
“CVE-2026-90711 weaponizes the agentic attack pattern formalized under AAP-002.”
- [technical_analysis]Pillar Security demonstrated that executing export BASH_ENV in Auto-Run causes bash to source hostile payloads upon subsequent commands. — Source: Pillar Security Research: Bypassing Cursor Auto-Run: When Shell Built-ins Lead to Host RCE (Reliability: HIGH)
1. Technical Context & Affected Software Matrix
Section titled “1. Technical Context & Affected Software Matrix”The proxy-addr module determines client addresses behind reverse proxies by traversing X-Forwarded-For headers from right to left until an untrusted IP address is encountered.
| Parameter | Technical Specification | Operational Significance |
|---|---|---|
| CVE Identifier | CVE-2026-90711 | NVD, GitHub Advisory GHSA-jqcg-44mw-7w3h |
| Vulnerability Class | Authentication Bypass by Spoofing (CWE-290) | Netmask calculation flaw in IPv4-mapped IPv6 ranges |
| Vulnerable Component | proxy-addr (functions compile and parseNetmask) | IP trust evaluation and header parsing pipeline |
| Root Mechanism | Misinterpretation of prefix lengths < 96 on IPv4-mapped IPv6 CIDR blocks | Matches 0.0.0.0/0, trusting all public IPv4 internet traffic |
| Attack Vector | Network (AV:N) via crafted X-Forwarded-For HTTP request headers | Remote unauthenticated HTTP requests |
| Privileges Required | None (PR:N) | Pre-authentication exploitation |
| User Interaction | None (UI:N) | Zero user interaction required |
| Affected Versions | >= 1.1.0, <= 2.0.7 | Broadly deployed in Express, Koa, and NestJS ecosystems |
| Remediated Version | 2.0.8 | Enforces prefix translation and explicit range validation |
2. Vulnerability Anatomy & Root Cause Analysis
Section titled “2. Vulnerability Anatomy & Root Cause Analysis”The IPv4-Mapped IPv6 Architecture
Section titled “The IPv4-Mapped IPv6 Architecture”Under RFC 4291, IPv4 addresses can be embedded into IPv6 addresses using the IPv4-mapped format:
IPv4 10.0.0.1 -> IPv6 ::ffff:10.0.0.1 (::ffff:0a00:0001)
In 128-bit binary representation:
- Bits 0 to 79: All zeros (
0000...) - Bits 80 to 95: All ones (
1111..., corresponding toffff) - Bits 96 to 127: The 32-bit IPv4 address (
10.0.0.1)
A proper subnet mask covering an IPv4 /8 subnet in IPv6 space must cover the 96 leading bits plus the 8 bits of the IPv4 mask:
Correct IPv6 Prefix Length = 96 + 8 = 104 -> ::ffff:10.0.0.0/104
The Bitwise Mask Underflow in proxy-addr
Section titled “The Bitwise Mask Underflow in proxy-addr”In vulnerable versions (<= 2.0.7), when an administrator or cloud deployment script configured a trust range using shorthand IPv4-mapped notation like ::ffff:10.0.0.0/8, the parser did not translate the prefix length:
// Vulnerable netmask parsing logic in proxy-addr <= 2.0.7function parseNetmask(netmask) { if (netmask.indexOf('/') !== -1) { var parts = netmask.split('/'); var addr = ipaddr.parse(parts[0]); var range = parseInt(parts[1], 10);
// FLAW: If addr is an IPv4-mapped IPv6 address (kind === 'ipv6'), // 'range' (8) is applied directly to the 128-bit address without adding 96! return [addr, range]; } // ...}When checking whether an incoming client connection (req.connection.remoteAddress) matches the subnet:
- An incoming connection from an external attacker arrives as an IPv4 address, which Node.js presents as
::ffff:203.0.113.50. - The subnet matcher compares the first 8 bits of
::ffff:203.0.113.50against the first 8 bits of::ffff:10.0.0.0. - Because both addresses begin with
0000:0000:..., their first 8 bits are identical (0x00). - The bitwise comparison returns
true!
As a result, every single IPv4 client in the world matches the /8 mask. The application concludes that the direct client TCP socket originates from a trusted reverse proxy.
// Express.js IP resolution workflow (req.ip)function getClientIp(req, trust) { var addrs = allAddrs(req); // e.g. [ "127.0.0.1", "203.0.113.50" ] for (var i = 0; i < addrs.length; i++) { // trust(203.0.113.50) returns TRUE due to CVE-2026-90711! if (!trust(addrs[i], i)) { return addrs[i]; } } return addrs[addrs.length - 1]; // Evaluates all the way to the attacker's fake IP!}3. Threat Vectors, Exploitation Mechanics & Attack Flow
Section titled “3. Threat Vectors, Exploitation Mechanics & Attack Flow”Attack Flow Architecture
Section titled “Attack Flow Architecture”flowchart TD A["Remote Adversary (IP: 203.0.113.50)"] -->|"1. Injects crafted Header: X-Forwarded-For: 127.0.0.1"| B["Node.js / Express Web Application"] B -->|"Evaluates socket.remoteAddress (::ffff:203.0.113.50)"| C["proxy-addr (trust check against ::ffff:10.0.0.0/8)"] C -->|"Prefix /8 matches first 8 zero-bits of both IPv6 addresses"| D["Bug: Returns TRUE (Direct socket treated as trusted proxy!)"] D -->|"Traverses X-Forwarded-For header to the left"| E["Extracts Attacker's Spoofed IP: 127.0.0.1"] E -->|"req.ip evaluated as 127.0.0.1"| F["Internal Authorization & Rate Limiting Middleware"] F -->|"2. Checks: Is req.ip in [127.0.0.1, 10.0.0.0/8]?"| G{"Access Granted?"} G -->|"YES: Bypasses Auth & Rate Limits"| H["Internal Admin Console / Agent Tool Webhook"] H -->|"3. Executes privileged commands or dumps secrets"| I["Host & AI Agent Infrastructure Compromise"]Exploit Demonstration
Section titled “Exploit Demonstration”An unauthenticated attacker connects to the Express application and bypasses local-only middleware:
# Target endpoint restricted to localhost (127.0.0.1):# app.get('/admin/debug/secrets', (req, res) => {# if (req.ip !== '127.0.0.1') return res.status(403).send('Forbidden');# res.json(process.env);# });
# Exploitation payload:curl -H "X-Forwarded-For: 127.0.0.1" \ -H "Host: api.victim-cloud.com" \ https://api.victim-cloud.com/admin/debug/secretsBecause proxy-addr erroneously treats the remote connection as trusted, Express populates req.ip with 127.0.0.1, completely neutralizing the authorization check and returning the application’s environment variables.
4. Forensic Execution Flow, Artifacts & Post-Exploitation Tactics
Section titled “4. Forensic Execution Flow, Artifacts & Post-Exploitation Tactics”Operational Impacts on Enterprise Applications
Section titled “Operational Impacts on Enterprise Applications”- Bypass of Administrative IP Restrictions: Microservices exposing internal endpoints (
/metrics,/admin,/v1/agent/tools,/actuator) guarded by IP checks are exposed to direct internet invocation. - Rate Limit Annihilation: Libraries such as
express-rate-limittrack connection frequencies byreq.ip. An attacker rotatingX-Forwarded-For: 10.0.0.Xon every request sends unlimited credential stuffing or API brute-force requests without triggering rate limits. - Forensic Audit Log Corruption: Security Information and Event Management (SIEM) ingestion pipelines parsing web server access logs log the spoofed IP address, leading incident response teams to investigate internal benign IP addresses instead of the attacker’s true origin.
- Geo-Fencing Circumvention: Applications enforcing regional compliance (e.g. EU GDPR or banking origin restrictions) can be bypassed by supplying an IP address from an approved geographic territory.
Forensic Artifacts & Detection Indicators
Section titled “Forensic Artifacts & Detection Indicators”When conducting post-incident analysis for CVE-2026-90711 exploitation:
- Socket vs Header Discrepancies: Compare the socket remote address recorded by TCP load balancers (AWS ALB, Cloudflare, HAProxy) against the
req.iplogged by Node.js. A connection arriving directly from a public IP that asserts an internalX-Forwarded-Forindicates exploitation. - Log Signatures:
[ACCESS LOG] socket_ip=203.0.113.50 resolved_ip=127.0.0.1 uri="/admin/backup" status=200[ACCESS LOG] socket_ip=203.0.113.50 resolved_ip=10.244.0.1 uri="/api/v1/agent/execute" status=200
- Rapidly Rotating Private IP Addresses: Sudden bursts of traffic from public IPs presenting consecutive private IP headers (
10.0.0.1,10.0.0.2,10.0.0.3) designed to evade rate limiters.
5. Detection Engineering & Sigma Rules
Section titled “5. Detection Engineering & Sigma Rules”Sigma Rule: Suspicious Internal IP Header Spoofing on External Requests
Section titled “Sigma Rule: Suspicious Internal IP Header Spoofing on External Requests”title: Potential Client IP Spoofing via X-Forwarded-For (CVE-2026-90711)id: c714a890-e832-4211-9a71-d10907110001status: experimentaldescription: Detects incoming HTTP requests arriving from external IP addresses asserting loopback or RFC1918 addresses in the X-Forwarded-For header to access sensitive paths.author: Hermes Codex Cyber Threat Intelligencedate: 2026-09-16references: - https://github.com/advisories/GHSA-jqcg-44mw-7w3h - https://nvd.nist.gov/vuln/detail/CVE-2026-90711logsource: category: webserver product: express / nginx / traefikdetection: selection_header: cs-method: - 'GET' - 'POST' - 'PUT' - 'DELETE' http_x_forwarded_for|startswith: - '127.' - '10.' - '192.168.' - '172.16.' - '172.17.' - '172.18.' - '172.19.' - '172.20.' - '172.21.' - '172.22.' - '172.23.' - '172.24.' - '172.25.' - '172.26.' - '172.27.' - '172.28.' - '172.29.' - '172.30.' - '172.31.' - '::1' selection_sensitive: cs-uri-stem|contains: - '/admin' - '/api/internal' - '/webhook' - '/actuator' - '/debug' filter_internal_source: c-ip|startswith: - '10.' - '172.16.' - '192.168.' - '127.' condition: selection_header and selection_sensitive and not filter_internal_sourcefields: - c-ip - http_x_forwarded_for - cs-uri-stem - sc-statusfalsepositives: - Misconfigured upstream reverse proxies omitting proper header sanitizationlevel: hightags: - attack.defense_evasion - attack.t1562.001 - attack.initial_access - cve.2026.907116. Hardening, Remediation & Verification
Section titled “6. Hardening, Remediation & Verification”-
Upgrade proxy-addr to Version 2.0.8 or Later: Update
proxy-addrin your root package and check for transitive dependencies usingnpm ls:Terminal window npm install proxy-addr@^2.0.8npm update proxy-addrnpm ls proxy-addr -
Correct IPv4-Mapped IPv6 Subnet Configurations: If your application or infrastructure configurations define custom trust ranges, avoid shorthand IPv4 prefixes on IPv6 notation. Either use standard IPv4 notation or supply the full 128-bit prefix (96 + prefix):
// VULNERABLE CONFIGURATION:app.set('trust proxy', '::ffff:10.0.0.0/8'); // Matches all IPv4!// SECURE CONFIGURATION (Option A - Standard IPv4 notation):app.set('trust proxy', '10.0.0.0/8');// SECURE CONFIGURATION (Option B - Explicit IPv6 prefix length):app.set('trust proxy', '::ffff:10.0.0.0/104'); -
Sanitize Headers at Perimeter Reverse Proxies (Nginx / HAProxy): Ensure your edge reverse proxy completely overwrites the incoming
X-Forwarded-Forheader rather than appending to client-supplied values:# Secure Nginx edge configuration# $remote_addr is the true Layer 4 IP of the connecting clientproxy_set_header X-Forwarded-For $remote_addr; -
Verify Dependency Resolution: Execute a security audit check across all installed Node.js services to ensure no vulnerable sub-dependencies remain:
Terminal window npx audit-ci --high --package-manager npm