Skip to content

CVE-2026-90711: Client IP Address Spoofing and Trust Boundary Bypass via IPv4-Mapped IPv6 CIDR Parsing Flaw in proxy-addr

HERMES

HERMES THREAT SCORE & ECOSYSTEM BLAST RADIUS

Target: proxy-addr (Node.js) & Downstream Frameworks (Express req.ip, Koa, NestJS, Fastify)
Confidence: 96%
91 / 100
CRITICAL

Measures real-world operational relevance, exploit weaponization, and active threat posture.

Dimension Breakdown
Exploitability 19 / 20
Threat Activity 16 / 20
Weaponization 18 / 20
Exposure 19 / 20
Prevalence 20 / 20
Impact 18 / 20
Exploit Maturity 18 / 20
Attack Chain Potential 19 / 20
⚖️ Divergence & Operational Rationale

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

HASS AGENTIC SEVERITY & PERIMETER AUTHENTICATION COLLAPSE

Target: AI Agent Ingress Gateways, Webhook Receivers & MCP Server Network Boundaries
Confidence: 92%
78 / 100
HIGH

Measures specific systemic risk arising from autonomy, tool authority, and cascading execution.

Dimension Breakdown
Autonomy 14 / 20
Tool Access 16 / 20
Privilege 14 / 15
Persistence 10 / 15
External Impact 12 / 15
Propagation 12 / 15
⚖️ Divergence & Operational Rationale

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.

🕸️ Connected Knowledge Graph & Provenance

CVE-2026-90711: Client IP Address Spoofing and Trust Boundary Bypass via IPv4-Mapped IPv6 CIDR Parsing Flaw in proxy-addrVULNERABILITY

Connected Nodes: 1
Active Relationships (Outgoing)
→ exploitsAGENTIC ATTACK_PATTERNAAP-002: Indirect Context Injection
92% VERY_HIGH

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.”

Supporting Verified Evidence:

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.

ParameterTechnical SpecificationOperational Significance
CVE IdentifierCVE-2026-90711NVD, GitHub Advisory GHSA-jqcg-44mw-7w3h
Vulnerability ClassAuthentication Bypass by Spoofing (CWE-290)Netmask calculation flaw in IPv4-mapped IPv6 ranges
Vulnerable Componentproxy-addr (functions compile and parseNetmask)IP trust evaluation and header parsing pipeline
Root MechanismMisinterpretation of prefix lengths < 96 on IPv4-mapped IPv6 CIDR blocksMatches 0.0.0.0/0, trusting all public IPv4 internet traffic
Attack VectorNetwork (AV:N) via crafted X-Forwarded-For HTTP request headersRemote unauthenticated HTTP requests
Privileges RequiredNone (PR:N)Pre-authentication exploitation
User InteractionNone (UI:N)Zero user interaction required
Affected Versions>= 1.1.0, <= 2.0.7Broadly deployed in Express, Koa, and NestJS ecosystems
Remediated Version2.0.8Enforces prefix translation and explicit range validation

2. Vulnerability Anatomy & Root Cause Analysis

Section titled “2. Vulnerability Anatomy & Root Cause Analysis”

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 to ffff)
  • 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

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.7
function 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:

  1. An incoming connection from an external attacker arrives as an IPv4 address, which Node.js presents as ::ffff:203.0.113.50.
  2. The subnet matcher compares the first 8 bits of ::ffff:203.0.113.50 against the first 8 bits of ::ffff:10.0.0.0.
  3. Because both addresses begin with 0000:0000:..., their first 8 bits are identical (0x00).
  4. 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”
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"]

An unauthenticated attacker connects to the Express application and bypasses local-only middleware:

Terminal window
# 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/secrets

Because 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”
  1. 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.
  2. Rate Limit Annihilation: Libraries such as express-rate-limit track connection frequencies by req.ip. An attacker rotating X-Forwarded-For: 10.0.0.X on every request sends unlimited credential stuffing or API brute-force requests without triggering rate limits.
  3. 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.
  4. 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.

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.ip logged by Node.js. A connection arriving directly from a public IP that asserts an internal X-Forwarded-For indicates 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.

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-d10907110001
status: experimental
description: 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 Intelligence
date: 2026-09-16
references:
- https://github.com/advisories/GHSA-jqcg-44mw-7w3h
- https://nvd.nist.gov/vuln/detail/CVE-2026-90711
logsource:
category: webserver
product: express / nginx / traefik
detection:
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_source
fields:
- c-ip
- http_x_forwarded_for
- cs-uri-stem
- sc-status
falsepositives:
- Misconfigured upstream reverse proxies omitting proper header sanitization
level: high
tags:
- attack.defense_evasion
- attack.t1562.001
- attack.initial_access
- cve.2026.90711

  1. Upgrade proxy-addr to Version 2.0.8 or Later: Update proxy-addr in your root package and check for transitive dependencies using npm ls:

    Terminal window
    npm install proxy-addr@^2.0.8
    npm update proxy-addr
    npm ls proxy-addr
  2. 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');
  3. Sanitize Headers at Perimeter Reverse Proxies (Nginx / HAProxy): Ensure your edge reverse proxy completely overwrites the incoming X-Forwarded-For header rather than appending to client-supplied values:

    # Secure Nginx edge configuration
    # $remote_addr is the true Layer 4 IP of the connecting client
    proxy_set_header X-Forwarded-For $remote_addr;
  4. 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

Section titled “7. Strategic Cross-References & Internal Links”