Scroll to top

CVE-2026-101901:Node.js サーバーをクラッシュさせ得る、axios の HTTP/2 に関する重要度「高」の脆弱性

CVE-2026-101901 axios HTTP/2 vulnerability

CVE: CVE-2026-101901
GitHub Advisory: GHSA-542g-h47m-68v8
Severity: High
CVSS: 8.2 / 10
Affected Package: Axios
Affected Versions: >= 1.13.0, < 1.20.0
Fixed Version: 1.20.0
Weakness: CWE-400 — Uncontrolled Resource Consumption
Researcher Credit: HackingRepo / RelunSec

Executive Summary

A denial-of-service vulnerability in Axios's experimental Node.js HTTP/2 implementation can cause an application's entire Node.js process to terminate when an HTTP/2 session emits an unhandled error event.

The vulnerability affects server-side Axios applications that explicitly enable:

httpVersion: 2

When Axios establishes or reuses an HTTP/2 session through its internal Http2Sessions implementation, certain network or session failures can generate a ClientHttp2Session error event.

In vulnerable versions, Axios did not register the necessary error handler on that session.

Node.js therefore interprets the event as an unhandled EventEmitter error, throws an exception, and may terminate the process instead of returning a normal rejected Axios Promise.

For applications where an attacker can influence the destination URL—or controls the remote HTTP/2 endpoint—this behavior can be converted into a remote denial-of-service condition.


The Core Problem

Developers normally expect Axios failures to behave like this:

Network Error
      │
      ▼
Axios catches failure
      │
      ▼
Promise rejected
      │
      ▼
Application catch(error)
      │
      ▼
Application continues running

The vulnerable HTTP/2 path could instead behave like:

Attacker-controlled destination
      │
      ▼
Axios opens HTTP/2 session
      │
      ▼
ClientHttp2Session emits "error"
      │
      ▼
No session error listener
      │
      ▼
Node.js throws uncaught exception
      │
      ▼
PROCESS TERMINATES

This difference is important because even applications that correctly wrap Axios requests in try/catch may still crash.

The failure happens at the EventEmitter/session layer rather than through Axios's normal Promise rejection path.


Node.js server code in an editor

Technical Root Cause

Axios HTTP/2 session management is implemented through:

Http2Sessions.getSession()

The affected logic creates an HTTP/2 connection using:

http2.connect(authority, options)

The returned object is a Node.js:

ClientHttp2Session

The vulnerable implementation registered handling for the session's close event, but did not properly handle the session's error event.

Conceptually, the vulnerable behavior looked like:

const session = http2.connect(authority, options);

session.on('close', () => {
  // cleanup
});

without an equivalent:

session.on('error', handler);

In Node.js, an EventEmitter emitting an error event without a registered error listener has special behavior.

Rather than being silently ignored, Node throws the error.

That can terminate the running process.


Why try/catch May Not Save the Application

Consider an application using Axios correctly:

try {
  const response = await axios.get(url, {
    httpVersion: 2
  });

  console.log(response.data);
} catch (error) {
  console.error('Request failed:', error.message);
}

A developer would reasonably expect network problems to reach:

catch (error)

However, the vulnerable session-level error may be emitted independently through Node's EventEmitter mechanism.

The result can be:

Axios Promise
      │
      ├── expected → reject()
      │
      └── vulnerable path
             │
             ▼
      ClientHttp2Session
             │
          "error"
             │
       no listener
             │
             ▼
     uncaught exception
             │
             ▼
        Node exits

This is what makes the issue particularly relevant for availability.


Minimal Proof of Concept

A minimal local reproduction can be demonstrated using an unreachable destination:

import axios from './index.js';

await axios.get('http://127.0.0.1:1/', {
  httpVersion: 2,
  timeout: 1000
});

On a vulnerable version, a session connection failure such as:

ECONNREFUSED

may result in an uncaught session error instead of only rejecting the Axios request.

The expected safe behavior is:

request rejected
↓
application handles error
↓
process survives

The vulnerable behavior is:

session error
↓
uncaught EventEmitter error
↓
process exits

Original Research Scenario

During the original investigation, I created a Node.js application using Axios with HTTP/2 enabled and dynamically varying HTTP/2 session options.

The application itself included normal error handling around the Axios request.

Despite that protection, triggering the vulnerable Axios HTTP/2 path caused the application to return an empty response and terminate unexpectedly.

Example request:

curl "http://127.0.0.1:3000/?http2optionId=hi"

Observed behavior included:

curl: (52) Empty reply from server

The important observation was that the surrounding application's own error-handling logic was not sufficient.

The failure originated from the internal Axios HTTP/2 session handling.

This led to investigation of the session lifecycle and eventually the missing handling of the ClientHttp2Session error event.


Fibre-optic strands glowing blue

Realistic Attack Scenario

Consider a backend service that retrieves external resources:

User
 │
 │ supplies URL
 ▼
Web Application
 │
 ▼
axios.get(userURL, {
    httpVersion: 2
})
 │
 ▼
Remote destination

If an attacker can influence:

userURL

the attacker may provide a destination that:

  • refuses the HTTP/2 connection;
  • becomes unavailable;
  • behaves incorrectly during HTTP/2 negotiation;
  • intentionally generates a session-level failure;
  • or is controlled by the attacker.

The resulting error may reach the vulnerable Axios HTTP/2 session.

Instead of simply generating:

HTTP 500

for one request, the vulnerable condition may terminate the Node.js worker itself.

Therefore:

1 malicious request
        │
        ▼
HTTP/2 session failure
        │
        ▼
Unhandled "error"
        │
        ▼
Node.js process crash
        │
        ▼
Service unavailable

Depending on the deployment architecture and process supervision, repeated triggering could cause recurring service disruption.


Security Impact

The primary impact is:

Availability

Successful exploitation may terminate the affected Node.js process.

GitHub assigned the advisory a High severity with a CVSS v4 score of 8.2.

The recorded metrics include:

Attack Vector:        Network
Attack Complexity:    Low
Attack Requirements:  Present
Privileges Required:  None
User Interaction:     None

Confidentiality:      None
Integrity:            None
Availability:         High

The official CVSS vector is:

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Conditions Required for Exploitation

This vulnerability does not affect every Axios deployment.

The relevant path requires:

httpVersion: 2

and the Node.js HTTP adapter.

A meaningful remote attack normally also requires the attacker to have some control over:

Request Destination

or to operate the destination server.

A typical vulnerable trust boundary looks like:

Untrusted user
     │
     ▼
Controls/influences URL
     │
     ▼
Application calls Axios
     │
     ▼
HTTP/2 enabled
     │
     ▼
Attacker-controlled or failing endpoint

What Is Not Affected?

The vulnerability does not apply to normal Axios usage in several important cases.

Default HTTP/1.1

Applications that do not explicitly enable Axios HTTP/2 are not affected by this specific issue.

Browser Axios

Browser implementations using:

XHR

or:

fetch

do not use the vulnerable Node.js ClientHttp2Session path.

Applications Without HTTP/2

If the application never configures:

httpVersion: 2

the vulnerable functionality is not reached.

Applications With No Untrusted Destination Control

Even where the vulnerable code is present, the remote attack surface is substantially reduced when destinations are completely fixed and trusted.


http2Options and the Original Investigation

During the original research, attacker-influenced values inside:

http2Options

were useful for reproducing session-management behavior.

However, this should not be interpreted to mean that Axios configuration itself is normally attacker-controlled.

Axios configuration should be treated as trusted application configuration.

The more important vulnerability is broader:

HTTP/2 session failures could escape Axios's normal Promise error-handling model and terminate the Node.js process.

The strongest practical threat model is therefore an application where an attacker can influence the HTTP/2 request destination.


JavaScript code on a screen

Why This Vulnerability Is Interesting

The bug demonstrates an important Node.js security engineering issue:

Promise Errors and EventEmitter Errors Are Different

Application developers may correctly protect asynchronous code with:

try {
  await operation();
} catch (error) {
  ...
}

but that does not automatically handle errors emitted independently by an EventEmitter.

For Node.js network objects, developers must also understand events such as:

error
close
timeout
aborted
connect

Failure to attach an appropriate error listener can turn what should be a recoverable network failure into a process-level availability problem.


Vulnerable Architecture

                    ┌───────────────────────┐
                    │     Remote User       │
                    └───────────┬───────────┘
                                │
                         attacker URL
                                │
                                ▼
                    ┌───────────────────────┐
                    │   Node.js Service     │
                    │                       │
                    │      axios.get()      │
                    │   httpVersion: 2      │
                    └───────────┬───────────┘
                                │
                                ▼
                    ┌───────────────────────┐
                    │    Http2Sessions      │
                    │     getSession()      │
                    └───────────┬───────────┘
                                │
                         http2.connect()
                                │
                                ▼
                    ┌───────────────────────┐
                    │ ClientHttp2Session    │
                    └───────────┬───────────┘
                                │
                           emits error
                                │
                                ▼
                      NO ERROR HANDLER
                                │
                                ▼
                    ┌───────────────────────┐
                    │ Uncaught Exception    │
                    └───────────┬───────────┘
                                │
                                ▼
                         PROCESS CRASH

Fixed Version

The official Axios advisory lists the affected versions as:

>= 1.13.0
< 1.20.0

The vulnerability is fixed in:

Axios 1.20.0

Users should upgrade to:

npm install axios@^1.20.0

or a newer supported release.


Temporary Mitigation

If upgrading is temporarily impossible, applications processing untrusted or user-influenced destinations should avoid Axios HTTP/2.

Remove:

httpVersion: 2

and use the standard HTTP/1.1 path until the dependency can be upgraded.

Applications should also avoid exposing arbitrary Axios configuration—particularly:

http2Options

—to untrusted callers.


Defensive Recommendations

Organizations using Axios server-side should consider several controls.

Upgrade Axios

Use:

1.20.0+

Identify HTTP/2 Usage

Search codebases for:

httpVersion: 2

Review User-Controlled URLs

Determine whether externally supplied input can influence Axios destinations.

Validate Outbound Destinations

Implement explicit allow-listing or destination-validation controls rather than relying solely on HTTP-client behavior.

Handle Node.js Network Errors Carefully

Any object derived from EventEmitter that can emit:

error

should have an appropriate listener when the library owns its lifecycle.

Use Process Supervision

PM2, Kubernetes, systemd, container orchestration, or similar supervision can reduce the operational impact of unexpected process termination, although process restarting does not fix the underlying vulnerability.


Disclosure and Attribution

The vulnerability was reported to the Axios project through GitHub's security advisory process.

GitHub's official advisory currently lists:

Reporter: HackingRepo

and includes the original report submitted during the investigation.

The final vulnerability identifiers are:

CVE-2026-101901
GHSA-542g-h47m-68v8

The advisory was published by the Axios maintainers on September 16, 2026.


Security Research Takeaway

This vulnerability is a good example of why security research cannot stop at the visible API boundary.

From the application developer's perspective:

await axios.get(...)

looks like a Promise-based API.

It is tempting to assume every failure will therefore become:

Promise.reject()

But underneath that API are:

HTTP/2 sessions
EventEmitters
Sockets
Connection lifecycle events
Session caches
Network exceptions

A failure in any of those layers can cross abstraction boundaries in unexpected ways.

In this case:

one missing session error handler

was enough to transform an ordinary connection failure into a remotely triggerable availability issue.

That is exactly the kind of edge case vulnerability research is designed to uncover.


References

Axios GitHub Security Advisory
https://github.com/axios/axios/security/advisories/GHSA-542g-h47m-68v8

CVE
CVE-2026-101901

GitHub Advisory
GHSA-542g-h47m-68v8

Axios Repository
https://github.com/axios/axios

報道・掲載記事

発見・報告:JoeCyberTech(GitHub: HackingRepo)

コメントを残す

メールアドレスをご確認ください
メッセージをご確認ください
ありがとうございます。メッセージは送信されました。
エラーが発生し、メールを送信できませんでした