Overview
Unrestricted Resource Consumption vulnerabilities in server-side JavaScript can occur when resource cleanup paths misbehave under high concurrency. CVE-2026-39865 describes a state corruption bug in Axios pre-1.13.2 related to HTTP/2 session cleanup within the Http2Sessions.getSession() path. The flaw arises when concurrent session closures manipulate the internal sessions array, potentially destabilizing the client process and creating denial-of-service conditions due to resource exhaustion or crashes. The CVE maps to CWE-400 (Unrestricted Resource Consumption) and CWE-662 (flawed cleanup of resources leading to instability). In Node.js (Express) apps that rely on Axios for outbound HTTP/2 requests, this class of bug can translate into unstable behavior under load or when interacting with servers that induce rapid session turnover.
Affected Versions
Axios pre-1.13.2 (e.g., versions < 1.13.2) are affected by CVE-2026-39865.
Code Fix Example
Node.js (Express) API Security Remediation
// Vulnerable (simulated pattern) demonstrating concurrent cleanup that mutates the sessions list
class Http2SessionManagerVulnerable {
constructor() {
this.sessions = [];
}
addSession(session) {
this.sessions.push(session);
}
async closeAll() {
await Promise.all(this.sessions.map(s => s.close().finally(() => {
const idx = this.sessions.indexOf(s);
if (idx !== -1) this.sessions.splice(idx, 1); // risky: mutating while other closures may still reference the array
})));
}
}
// Fixed (simulated) pattern that avoids in-place mutation during concurrent cleanup
class Http2SessionManagerFixed {
constructor() {
this.sessions = [];
}
addSession(session) {
this.sessions.push(session);
}
async closeAll() {
// Snapshot and clear the list before closing to avoid in-flight mutations
const toClose = this.sessions.slice();
this.sessions.length = 0;
await Promise.all(toClose.map(s => s.close()));
}
}
// Optional mock session to illustrate behavior
class MockSession {
constructor(id) { this.id = id; }
close() { return new Promise(resolve => setTimeout(resolve, 10)); }
}
// Example usage (not executed here):
// const mgrV = new Http2SessionManagerVulnerable();
// const mgrF = new Http2SessionManagerFixed();
// // add and close sessions concurrently to observe differences