Summary
Axios: ReDoS in fromDataURI data: URL parser freezes the Node event loop (DoS)
Axios for Node.js parses data: URLs in lib/helpers/fromDataURI.js. The current RFC-2397 parser uses a regular expression whose media type groups allow / inside both sides of the type/subtype match. A malformed data: URL containing many slashes and no comma forces the JavaScript regex engine to try many possible placements for the separator before failing.
Applications are affected when they pass untrusted URL strings to axios and do not reject or constrain data: URLs before axios parses them.
Affected Functionality
Affected:
- Node.js HTTP adapter data URL handling.
axios.get()or equivalent calls whereconfig.urlhas thedata:protocol.
Not affected:
- Browser fetch/XHR URL handling.
- Node requests where the application rejects
data:URLs before calling axios. - Older checked
0.xdata URL parser shape unless separately proven vulnerable.
Technical Details
lib/helpers/fromDataURI.js contains:
const DATA_URL_PATTERN = /^([^,;]+\/[^,;]+)?((?:;[^,;=]+=[^,;]+)*)(;base64)?,([\s\S]*)$/;
The [^,;]+ groups include /, so a long string of slashes without a comma can be partitioned around the required \/ in many ways before the match fails. The match runs before axios can apply request timeout behavior, so timeout does not mitigate the parsing pause.
Local timing on axios 1.18.1 with small payloads showed about 2.4 ms at 1000 slashes, 16.6 ms at 3000 slashes, and 71.5 ms at 6000 slashes, consistent with the submitted quadratic scaling while avoiding long-running payloads.
Proof of Concept of Attack
Constrained helper-level demonstration:
import axios from 'axios';
await axios.get('data:' + '/'.repeat(6000));
The request fails after parsing, but the failure is delayed by synchronous regex work. Larger payloads increase the pause substantially.
Workarounds
Reject data: URLs before passing untrusted input to axios, or enforce a strict maximum URL length for URL-fetching endpoints. Applications that do not need data: URL support should deny that protocol explicitly.
Original report
ReDoS in fromDataURI data: URL parser freezes the event loop (DoS)
Affected
- Package:
axios(Node.js http adapter) - Versions: 1.x (regex present on
v1.x, current release line) - File:
lib/helpers/fromDataURI.js - CWE-1333 (Inefficient Regular Expression Complexity)
Issue
fromDataURI parses data: URLs with this regex:
// lib/helpers/fromDataURI.js:9
const DATA_URL_PATTERN = /^([^,;]+\/[^,;]+)?((?:;[^,;=]+=[^,;]+)*)(;base64)?,([\s\S]*)$/;
The mediatype tokens [^,;]+ include /, so they can span multiple slashes ambiguously. A data: URL made of many slashes with no comma forces the engine to try every way to place the single \/ divider before failing, quadratic O(n²) backtracking. It runs synchronously on the main thread, so the whole Node event loop is frozen for the entire parse. Reachable through the public API on the Node http adapter (axios.get(url)); the browser fetch/xhr adapters are not affected because they do not call fromDataURI.
A configured timeout does not help: the freeze happens during parsing, before any network timer can fire.
PoC (minimal)
import axios from 'axios';
// ~256 KB data: URL of pure slashes, no comma
await axios.get('data:' + '/'.repeat(262139)); // blocks the event loop ~6 min, then throws
Lab results
Single-threaded "fetch a user-supplied URL" service (link-preview style) calling axios.get on a JSON body { "url": "..." }, with timeout: 1000 set.
Scaling is clean O(n²) (constant k ≈ 5.6e-6 ms/byte², stable across sizes):
| data: URL size | Event-loop freeze (one request) |
|---|---|
| 32 KB | 6.3 s (measured end-to-end; server logged event loop BLOCKED for 6.30s) |
| 64 KB | ~24 s |
| 128 KB | ~96 s |
| 256 KB | ~385 s (~6.4 min) |
| 1 MB | ~100 min |
During the freeze the server answers nothing: a /healthz liveness probe times out for the whole window, and the server's own event-loop monitor cannot even log until the parse finishes. In a run through an intercepting proxy, the proxy hit its 120 s upstream timeout and gave up, while the origin stayed pegged at 100% CPU on one core past that, client/proxy timeouts do not mitigate it.
The attacker controls only the URL string and needs no auth. ~256 KB every ~6 min (≈ 0.7 bytes/sec) keeps a server permanently unavailable.
Impact
Unauthenticated remote denial of service. One small request takes a Node service fully offline for minutes; a trickle keeps it down indefinitely.
CVSS 3.1: 7.5 (High), AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.
Impact
An attacker can make the Node.js event loop spend significant synchronous CPU time parsing a single malformed URL. In a server that accepts a URL from an HTTP request and calls axios.get(url), this can block unrelated requests and health checks until parsing completes.
The issue is availability-only. It does not disclose data or modify requests.
A regular expression with worst-case exponential or polynomial matching time is applied to untrusted input, causing excessive CPU use. Typical impact: denial of service when input is crafted to trigger backtracking.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
RFC 2045 type/subtype tokens never contain /. Excluding / from those two character classes removes the ambiguity and the backtracking:
const DATA_URL_PATTERN = /^([^,;/]+\/[^,;/]+)?((?:;[^,;=]+=[^,;]+)*)(;base64)?,([\s\S]*)$/;
Worst-case parse drops from ~2600 ms to ~0.002 ms. All valid data: URLs, including slashes in the body, parse identically.
Frequently Asked Questions
- What is CVE-2026-101903? CVE-2026-101903 is a high-severity inefficient regular expression (ReDoS) vulnerability in axios (npm), affecting versions >= 1.16.1, < 1.20.0. It is fixed in 1.20.0. A regular expression with worst-case exponential or polynomial matching time is applied to untrusted input, causing excessive CPU use.
- Which versions of axios are affected by CVE-2026-101903? axios (npm) versions >= 1.16.1, < 1.20.0 is affected.
- Is there a fix for CVE-2026-101903? Yes. CVE-2026-101903 is fixed in 1.20.0. Upgrade to this version or later.
- Is CVE-2026-101903 exploitable, and should I be worried? Whether CVE-2026-101903 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-101903 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-101903? Upgrade
axiosto 1.20.0 or later.