Apr 8, 2026·7 min read·29 visits
A bug in the Axios HTTP/2 session cleanup code (lib/adapters/http.js) causes an unhandled TypeError when mutating a session array during iteration. Malicious servers can trigger this via concurrent session closures, leading to an application crash (DoS). Fixed in version 1.13.2.
Axios versions prior to 1.13.2 contain a state corruption vulnerability in the HTTP/2 session cleanup routine. The improper handling of array mutations during backwards iteration allows a malicious HTTP/2 server to crash the Node.js process by terminating multiple sessions concurrently.
Axios is a widely deployed promise-based HTTP client used in both browser environments and Node.js backend services. The Node.js adapter within Axios natively supports HTTP/2 multiplexing, managing client sessions dynamically based on target authorities (combinations of host and port). The vulnerability, identified as CVE-2026-39865, resides within the HTTP/2 session tracking logic located in lib/adapters/http.js.
The specific flaw manifests in the Http2Sessions.getSession() method, which handles the lifecycle of active HTTP/2 sessions. When a session terminates, a callback named removeSession is triggered to purge the defunct session from an internal tracking array. This callback attempts to mutate the session array in-place without safely terminating the surrounding loop, leading to an invalid state.
This behavior is classified under CWE-400 (Uncontrolled Resource Consumption) and CWE-662 (Improper Synchronization), as the implementation fails to safely manage shared state across asynchronous callback boundaries. When triggered, the resulting state corruption produces a fatal exception that terminates the hosting application.
The ultimate impact is a process-level Denial of Service (DoS). Downstream applications relying on Axios for server-to-server HTTP/2 communication are entirely offline once the unhandled exception terminates the Node.js runtime process.
The underlying defect occurs during array manipulation within an asynchronous event handler. Axios tracks HTTP/2 connections by storing session references in a multidimensional array or list bound to specific network authorities. When a connection emits a close event, the removeSession function iterates over the entries array backward using a while (i--) loop to locate and eliminate the closed session.
When the matching session is found, the code executes entries.splice(i, 1). The splice method modifies the array in-place by removing the element and shifting the indices of all subsequent elements. This mutation fundamentally invalidates the current loop index i regarding the remaining elements in the array.
In scenarios where the target authority contains multiple sessions, the removeSession logic fails to immediately exit the loop after the splice operation. The loop continues to iterate, decrementing i and accessing the array. Because the array length has decreased and elements have shifted, the loop attempts to access elements that are now out of bounds or reference undefined values.
In a high-concurrency environment, multiple close events trigger the removeSession function in parallel. The continued iteration over the shifted array causes a TypeError when the code tries to read properties of an undefined element. Since this exception originates within an asynchronous network event callback without a surrounding catch block, the error bubbles up and crashes the entire Node.js process.
The vulnerable implementation resides in the cleanup routine for HTTP/2 sessions. The code iterates through the entries array in reverse order, identifies the closed session, and removes it. The failure to terminate the loop after this operation guarantees undefined behavior if the array contains multiple elements.
// Vulnerable Implementation in lib/adapters/http.js
while (i--) {
if (entries[i][0] === session) {
if (len === 1) {
delete this.sessions[authority];
} else {
entries.splice(i, 1);
}
// Loop continues execution over mutated array
}
}The official patch applied in commit 12c314b603e7852a157e93e47edb626a471ba6c5 addresses the flaw by introducing an immediate return statement. This ensures that once the target session is removed, the loop execution halts, preventing any further access to the modified array.
// Patched Implementation in lib/adapters/http.js
while (i--) {
if (entries[i][0] === session) {
if (len === 1) {
delete this.sessions[authority];
} else {
entries.splice(i, 1);
}
return; // Immediate exit prevents iteration on mutated array
}
}This single line corrects the control flow issue. By terminating the function immediately after the splice or delete operation, the code completely bypasses the risk of accessing out-of-bounds indices or undefined elements. This fix is comprehensive for this specific code path, though subsequent commits like 0588880ac7ddba7594ef179930493884b7e90bf5 provide additional safeguards related to module exports and socket hang-ups.
Exploiting CVE-2026-39865 requires an attacker to control the HTTP/2 server endpoint that an Axios client communicates with, or to be positioned as a Man-in-the-Middle capable of injecting HTTP/2 control frames. The attacker does not need authentication, but must be able to accept incoming HTTP/2 connections from the vulnerable client.
The attack begins when the Axios client establishes multiple HTTP/2 sessions with the malicious server. Once the sessions are established and multiplexed streams are open, the malicious server intentionally aborts the connections simultaneously. This is typically achieved by transmitting a barrage of HTTP/2 GOAWAY frames or abruptly dropping the TCP sockets.
The simultaneous termination forces the Node.js networking stack to emit multiple close events in rapid succession. This triggers the vulnerable removeSession callback concurrently across the event loop ticks. The array mutation flaw is then exercised repeatedly, generating the fatal TypeError and crashing the application.
The impact of this vulnerability is isolated entirely to system availability. An attacker successfully exploiting CVE-2026-39865 causes the host Node.js application to crash immediately. The vulnerability does not allow for arbitrary code execution, nor does it provide the attacker with unauthorized read or write access to application data.
The CVSS v3.1 vector is evaluated as CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H, producing a base score of 5.9 (Medium). The Attack Complexity (AC) is categorized as High because the attacker relies on the target application actively establishing outbound HTTP/2 connections to an attacker-controlled endpoint. The exploitation requires specific timing and concurrency conditions to trigger the crash reliably.
Despite the medium base score, the operational consequences for backend architectures can be severe. In microservice environments where a Node.js API gateway utilizes Axios to route traffic via HTTP/2, a compromised or maliciously configured downstream service can repeatedly crash the gateway. This creates a cascading failure scenario where the core routing infrastructure becomes entirely unavailable to legitimate users.
The vulnerability is not currently listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, and there is no public evidence of active exploitation in the wild or utilization in ransomware campaigns. However, the trivial nature of the trigger mechanism makes it an attractive vector for service disruption attacks.
The primary remediation strategy is upgrading the Axios library to version 1.13.2 or later. Developers should audit their dependency trees, including transitive dependencies, to ensure no legacy versions of Axios are bundled in the application. Tools like npm audit or yarn audit will flag the vulnerable package.
If immediate upgrading is impossible due to dependency conflicts, administrators can mitigate the vulnerability by disabling HTTP/2 support within the Axios configuration. By forcing Axios to downgrade to HTTP/1.1, the application bypasses the vulnerable Http2Sessions.getSession() logic entirely. This is achieved by explicitly omitting the HTTP/2 agent or configuring the request parameters to forbid protocol negotiation.
Additionally, operations teams must ensure that Node.js applications are deployed with process managers (such as PM2, systemd, or Kubernetes ReplicaSets) configured to automatically restart the application upon an unexpected crash. While this does not prevent the DoS attack, it reduces the mean time to recovery (MTTR) and mitigates the long-term impact of the crash.
Network detection of this exploit is challenging because the GOAWAY frames or sudden connection resets are encrypted within the TLS tunnel. Therefore, security teams should focus on application-level monitoring, specifically tracking unhandled exception logs that mention lib/adapters/http.js or removeSession.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Axios Axios | < 1.13.2 | 1.13.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 / CWE-662 |
| Attack Vector | Network |
| CVSS v3.1 Score | 5.9 (Medium) |
| Impact | Denial of Service (Process Crash) |
| Exploit Status | Proof of Concept |
| CISA KEV | Not Listed |
The software does not properly control the allocation and maintenance of a limited resource (sessions/memory), which can lead to exhaustion or crashes.
CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.
An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.
An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.
CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.
An improper handling of highly compressed data (decompression bomb) vulnerability exists in the Elixir Tesla HTTP client when utilizing response decompression middlewares. By serving highly compressed responses or stacked content-encoding headers, a malicious server can cause arbitrary heap exhaustion, leading to a denial of service (DoS) crash in the BEAM virtual machine.
A high-severity security vulnerability in Elixir's Tesla HTTP client library (CVE-2026-48595) allows unauthenticated remote attackers to harvest sensitive credentials, including Authorization headers and cookies. The flaw resides in the 'Tesla.Middleware.FollowRedirects' component, which performs case-sensitive lookups when stripping credentials during cross-origin redirects. Because HTTP headers are case-insensitive by RFC specifications, standard canonical casing (e.g., 'Authorization') bypasses the lowercase-only blocklist, leaking tokens to untrusted external redirect destinations.