CVE-2026-62985 Overview
CVE-2026-62985 is an uncaught exception vulnerability [CWE-248] in request-filtering-agent, a Node.js http(s).Agent implementation that blocks requests to private and reserved IP addresses. Versions prior to 3.2.1 synchronously throw from createConnection when a literal private-IP host such as 169.254.169.254 or 127.0.0.1 is rejected. Node.js http.request and http.get expect connection failures asynchronously, so the throw bypasses req.on('error') handlers and surfaces as an uncaught exception that can terminate the process. The issue is fixed in version 3.2.1.
Critical Impact
Attackers who can influence outbound request URLs can crash Node.js applications by supplying literal private-IP hosts, causing denial of service.
Affected Products
- request-filtering-agent versions prior to 3.2.1
- Node.js applications using RequestFilteringHttpAgent
- Node.js applications using RequestFilteringHttpsAgent
Discovery Timeline
- 2026-09-22 - CVE-2026-62985 published to NVD
- 2026-09-23 - Last updated in NVD database
Technical Details for CVE-2026-62985
Vulnerability Analysis
The request-filtering-agent package protects Node.js applications from server-side request forgery (SSRF) by blocking connections to private and reserved IP ranges. In versions prior to 3.2.1, the RequestFilteringHttpAgent and RequestFilteringHttpsAgent classes implement rejection logic inside createConnection. When a request targets a literal private-IP host, the agent throws a synchronous error rather than emitting it through the socket's error channel.
Node.js http.request and http.get assume that transport-level failures are delivered asynchronously to req.on('error') listeners. A synchronous throw from createConnection escapes the request's error handler and propagates up the call stack. If the caller does not wrap the invocation in a try/catch, the exception becomes uncaught and terminates the Node.js process.
Hostnames resolved through the asynchronous DNS lookup path are unaffected because rejection occurs after the lookup callback, matching Node's expected error delivery model. The vulnerability is limited to literal IP hosts, but any application accepting user-controlled URLs is exposed.
Root Cause
The root cause is an error-delivery asymmetry between the agent's synchronous rejection path and Node's asynchronous connection contract. createConnection is expected to signal failure by destroying a socket with an error or invoking a connection listener, not by throwing.
Attack Vector
A remote attacker submits a URL containing a literal private or reserved IP address such as http://127.0.0.1/ or http://169.254.169.254/ to any endpoint that forwards outbound HTTP requests through the vulnerable agent. The synchronous throw bypasses application error handlers and crashes the Node.js worker, producing a denial-of-service condition.
// Patch from src/request-filtering-agent.ts (v3.2.1)
const createConnectionErrorSocket = (
error: Error,
connectionListener?: (error: Error | null, socket: Duplex) => void
): net.Socket => {
const socket = new net.Socket();
if (connectionListener) {
connectionListener(error, socket);
} else {
socket.destroy(error);
}
return socket;
};
Source: GitHub Commit 9d12561. The fix returns an error-bearing socket instead of throwing, restoring asynchronous error delivery.
Detection Methods for CVE-2026-62985
Indicators of Compromise
- Unexpected Node.js process exits or worker restarts correlated with outbound HTTP request handling
- Application logs containing uncaught exceptions originating from request-filtering-agentcreateConnection
- Inbound requests supplying URLs with literal private-IP hosts such as 127.0.0.1, 169.254.169.254, 10.0.0.0/8, or 192.168.0.0/16
Detection Strategies
- Audit package.json and lockfiles across services for request-filtering-agent versions below 3.2.1
- Enable process.on('uncaughtException') telemetry and alert on stack traces referencing RequestFilteringHttpAgent or RequestFilteringHttpsAgent
- Inspect reverse proxy and application logs for user-controlled URL parameters containing IPv4 or IPv6 literals targeting reserved ranges
Monitoring Recommendations
- Track Node.js process restart frequency and crash-loop patterns in orchestration platforms such as Kubernetes
- Ingest application error logs into a centralized log platform and alert on repeated crashes tied to the same client identifier
- Monitor outbound connection attempts to private IP ranges from services that should only reach public destinations
How to Mitigate CVE-2026-62985
Immediate Actions Required
- Upgrade request-filtering-agent to version 3.2.1 or later across all Node.js services
- Wrap http.request and http.get calls that use the agent in try/catch blocks as a defense-in-depth measure until patching completes
- Validate and reject user-supplied URLs containing literal IP addresses at the application boundary
Patch Information
The fix is available in request-filtering-agent v3.2.1. Full technical context is documented in GitHub Security Advisory GHSA-r3r9-wp5j-pq5g. The patch replaces the synchronous throw with a socket that emits the error asynchronously, aligning with Node.js http.Agent expectations.
Workarounds
- Register a global process.on('uncaughtException') handler that logs the error and prevents process termination, accepting the operational tradeoffs
- Pre-validate request URLs with an allowlist of hostnames or a strict IP filter before invoking the agent
- Deploy Node.js workers behind a process supervisor that restarts crashed instances automatically to reduce downtime
# Upgrade to the patched version
npm install request-filtering-agent@^3.2.1
# Verify installed version
npm ls request-filtering-agent
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.