CVE-2026-21710 Overview
A flaw in Node.js HTTP request handling causes an uncaught TypeError when a request is received with a header named __proto__ and the application accesses req.headersDistinct. When this occurs, dest["__proto__"] resolves to Object.prototype rather than undefined, causing .push() to be called on a non-array. This exception is thrown synchronously inside a property getter and cannot be intercepted by error event listeners, meaning it cannot be handled without wrapping every req.headersDistinct access in a try/catch.
Critical Impact
Remote attackers can crash Node.js HTTP servers by sending specially crafted requests with a __proto__ header, causing unhandled exceptions that terminate the application process.
Affected Products
- Node.js 20.x
- Node.js 22.x
- Node.js 24.x
- Node.js 25.x
Discovery Timeline
- 2026-03-30 - CVE CVE-2026-21710 published to NVD
- 2026-04-01 - Last updated in NVD database
Technical Details for CVE-2026-21710
Vulnerability Analysis
This vulnerability exploits JavaScript's prototype chain behavior when handling HTTP headers in Node.js. The headersDistinct property getter processes incoming HTTP headers and stores them in a destination object. When a request contains a header named __proto__, the code attempts to access dest["__proto__"], which resolves to Object.prototype instead of undefined due to JavaScript's prototype inheritance model.
The core issue stems from improper handling of special property names in JavaScript. Since __proto__ is a special accessor property on all objects that references the object's prototype, accessing it returns the Object.prototype object rather than the expected header array. When the code subsequently calls .push() on this value expecting an array, it triggers a TypeError because Object.prototype does not have a push method.
This vulnerability is classified as CWE-770 (Allocation of Resources Without Limits or Throttling), as it allows resource exhaustion through application termination. The synchronous nature of the exception within a property getter makes it particularly dangerous because standard Node.js error handling patterns using event listeners cannot intercept it.
Root Cause
The root cause is a prototype pollution vector in the HTTP header parsing logic. The headersDistinct property getter fails to properly sanitize or validate header names before using them as object property keys. When the special __proto__ property name is used as a header, the JavaScript engine's prototype chain lookup behavior causes unexpected object resolution, leading to a type mismatch when array methods are invoked on the prototype object.
Attack Vector
The attack is network-based and requires no authentication or user interaction. An attacker can exploit this vulnerability by sending a malicious HTTP request to any Node.js HTTP server running an affected version. The request simply needs to include a header with the name __proto__. When the server application accesses req.headersDistinct (a common operation for header inspection), the uncaught exception crashes the server.
The vulnerability is particularly severe because:
- It affects all Node.js HTTP servers on vulnerable versions
- The exception cannot be caught using standard Node.js error handling patterns
- Only wrapping every req.headersDistinct access in try/catch provides protection
- A single malicious request can terminate the entire server process
Detection Methods for CVE-2026-21710
Indicators of Compromise
- HTTP requests containing headers with the name __proto__ or similar prototype-polluting property names
- Unexpected Node.js process crashes with TypeError stack traces referencing headersDistinct
- Application logs showing uncaught exceptions related to .push() method calls on non-array objects
- Repeated server restarts or process manager (PM2, systemd) restart events
Detection Strategies
- Implement web application firewall (WAF) rules to block HTTP requests containing __proto__ in header names
- Monitor Node.js application logs for TypeError exceptions mentioning headersDistinct or prototype-related errors
- Deploy network intrusion detection rules to identify malicious header patterns in HTTP traffic
- Configure application performance monitoring to alert on sudden process terminations
Monitoring Recommendations
- Enable verbose logging for HTTP request headers at the load balancer or reverse proxy level
- Set up process crash alerting through container orchestration or process managers
- Monitor for unusual patterns of rapid server restarts that may indicate exploitation attempts
- Implement request rate limiting to reduce the impact of denial-of-service attacks
How to Mitigate CVE-2026-21710
Immediate Actions Required
- Update Node.js to the latest patched version for your release line (20.x, 22.x, 24.x, or 25.x)
- Implement reverse proxy filtering to block requests with __proto__ headers before they reach Node.js
- Wrap all req.headersDistinct accesses in try/catch blocks as a temporary workaround
- Review application code for other potential prototype pollution entry points
Patch Information
Node.js has released security updates addressing this vulnerability in March 2026. Refer to the Node.js March 2026 Security Release for specific version numbers and download links. Organizations should prioritize updating to the patched versions immediately given the ease of exploitation and high availability impact.
Workarounds
- Deploy a reverse proxy (nginx, HAProxy) or WAF configured to reject requests containing __proto__ headers
- Wrap all req.headersDistinct property accesses in try/catch blocks to prevent unhandled exceptions
- Implement process restart automation using tools like PM2 or systemd to minimize downtime during attacks
- Consider rate limiting at the network edge to reduce the effectiveness of denial-of-service attempts
# Nginx configuration to block __proto__ headers
# Add to server or location block
if ($http___proto__ != "") {
return 400;
}
# Alternative: Use map directive for more complex filtering
map $http___proto__ $block_proto {
default 0;
"~." 1;
}
server {
if ($block_proto) {
return 400 "Bad Request";
}
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


