Axios: ReDoS (O(N²)) in shouldBypassProxy host normalization, reachable via untrusted redirect Location
Collected exploitation and prediction evidence
Risk source coverageCISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.
No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.
cve-program · CVE-2026-101906
PublishedAxios is a promise-based HTTP client for the browser and Node.js. From 1.15.0 until 1.20.0, Axios shouldBypassProxy applies a quadratic trailing-dot regular expression to redirect hostnames. HTTP_PROXY or HTTPS_PROXY is configured, NO_PROXY or no_proxy is non-empty, redirects are followed, and a crafted redirect Location contains many dots followed by a non-dot character. Hostname.replace(/.+$/, '') backtracks quadratically while processing the crafted redirect hostname. Synchronous regular-expression processing can block the Node.js event loop and cause denial of service. This issue is fixed in version 1.20.0.
- Source published
- 28 Sep 2026 17:32:40 UTC
- Source modified
- 28 Sep 2026 19:15:12 UTC
- Observed here
- 23 Oct 2026 15:48:27 UTC
- Source terms
- CVE Program Terms of Use
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 4.0 · 8.2 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
euvd · EUVD-2026-88383
PublishedAxios is a promise-based HTTP client for the browser and Node.js. From 1.15.0 until 1.20.0, Axios shouldBypassProxy applies a quadratic trailing-dot regular expression to redirect hostnames. HTTP_PROXY or HTTPS_PROXY is configured, NO_PROXY or no_proxy is non-empty, redirects are followed, and a crafted redirect Location contains many dots followed by a non-dot character. Hostname.replace(/.+$/, '') backtracks quadratically while processing the crafted redirect hostname. Synchronous regular-expression processing can block the Node.js event loop and cause denial of service. This issue is fixed in version 1.20.0.
EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.
Original publisher date fields
datePublished: Sep 28, 2026, 5:32:40 PM
dateUpdated: Sep 28, 2026, 7:15:12 PM
5 related source bulletins · separate from aliases
RHSA-2026:74871: Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update
CVE-2026-93450 · CVE-2026-101898 · CVE-2026-101900 · CVE-2026-101901 · CVE-2026-101902 · CVE-2026-101903 · CVE-2026-101904 · CVE-2026-101905 · CVE-2026-101906 · CVE-2026-101907 · CVE-2026-101908 · CVE-2026-101909
WID-SEC-W-2026-4410: IBM App Connect Enterprise: Mehrere Schwachstellen
CVE-2026-100699 · CVE-2026-100700 · CVE-2026-100701 · CVE-2026-100702 · CVE-2026-101898 · CVE-2026-101900 · CVE-2026-101901 · CVE-2026-101902 · CVE-2026-101903 · CVE-2026-101904 · CVE-2026-101905 · CVE-2026-101906 · CVE-2026-101907 · CVE-2026-101908 · CVE-2026-101909 · CVE-2026-101915 · CVE-2026-101916 · CVE-2026-104850 · CVE-2026-106444 · CVE-2026-106445 · CVE-2026-106446 · CVE-2026-110869 · CVE-2026-111767 · CVE-2026-15187 · CVE-2026-33937 · CVE-2026-83745 · CVE-2026-84003 · CVE-2026-86535 · CVE-2026-90776 · CVE-2026-91863 · CVE-2026-91864 · CVE-2026-91865 · CVE-2026-91866 · CVE-2026-91867 · CVE-2026-93687 · CVE-2026-93749 · CVE-2026-94645 · CVE-2026-94646 · CVE-2026-96294
RHSA-2026:74872: Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update
CVE-2026-101898 · CVE-2026-101900 · CVE-2026-101901 · CVE-2026-101902 · CVE-2026-101903 · CVE-2026-101904 · CVE-2026-101905 · CVE-2026-101906 · CVE-2026-101907 · CVE-2026-101908 · CVE-2026-101909
WID-SEC-W-2026-4056: Atlassian Produkte (Bamboo, Bitbucket, Confluence, Crucible, Fisheye und Jira): Mehrere Schwachstellen
CVE-2026-101898 · CVE-2026-101901 · CVE-2026-101903 · CVE-2026-101905 · CVE-2026-101906 · CVE-2026-101907 · CVE-2026-101909 · CVE-2026-12185 · CVE-2026-12802 · CVE-2026-12860 · CVE-2026-13006 · CVE-2026-13676 · CVE-2026-14682 · CVE-2026-18036 · CVE-2026-19534 · CVE-2026-19693 · CVE-2026-41842 · CVE-2026-41845 · CVE-2026-41850 · CVE-2026-49434 · CVE-2026-50750 · CVE-2026-53404 · CVE-2026-54399 · CVE-2026-54428 · CVE-2026-54512 · CVE-2026-54513 · CVE-2026-55153 · CVE-2026-55831 · CVE-2026-55833 · CVE-2026-56624 · CVE-2026-56745 · CVE-2026-58061 · CVE-2026-58062 · CVE-2026-59641 · CVE-2026-59645 · CVE-2026-59651 · CVE-2026-59903 · CVE-2026-62243 · CVE-2026-65182 · CVE-2026-65183 · CVE-2026-65637 · CVE-2026-65927 · CVE-2026-66422 · CVE-2026-67213 · CVE-2026-67214 · CVE-2026-68494 · CVE-2026-68495 · CVE-2026-68497 · CVE-2026-68498 · CVE-2026-68525 · CVE-2026-68569 · CVE-2026-68763 · CVE-2026-71888 · CVE-2026-71889 · CVE-2026-71891 · CVE-2026-73086 · CVE-2026-73507 · CVE-2026-73508 · CVE-2026-73634 · CVE-2026-73635 · CVE-2026-73646 · CVE-2026-75140 · CVE-2026-75595 · CVE-2026-75596 · CVE-2026-75975 · CVE-2026-76172 · CVE-2026-77185 · CVE-2026-84292 · CVE-2026-84375 · CVE-2026-93488 · CVE-2026-93491 · CVE-2026-93558 · CVE-2026-93690 · CVE-2026-93748 · CVE-2026-93994
RHSA-2026:74869: Red Hat Security Advisory: Red Hat Hardened Images RPMs Security Update
CVE-2026-93981 · CVE-2026-101898 · CVE-2026-101900 · CVE-2026-101901 · CVE-2026-101902 · CVE-2026-101903 · CVE-2026-101904 · CVE-2026-101905 · CVE-2026-101906 · CVE-2026-101907 · CVE-2026-101908 · CVE-2026-101909
- Source published
- Sep 28, 2026, 5:32:40 PM (timezone not stated)
- Source modified
- Sep 28, 2026, 7:15:12 PM (timezone not stated)
- Observed here
- 11 Nov 2026 05:28:17 UTC
- Source terms
- ENISA EUVD · source terms and attribution apply
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.
EUVD CVSS 4.0 · 8.2 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
nvd · CVE-2026-101906
PublishedAxios is a promise-based HTTP client for the browser and Node.js. From 1.15.0 until 1.20.0, Axios shouldBypassProxy applies a quadratic trailing-dot regular expression to redirect hostnames. HTTP_PROXY or HTTPS_PROXY is configured, NO_PROXY or no_proxy is non-empty, redirects are followed, and a crafted redirect Location contains many dots followed by a non-dot character. Hostname.replace(/.+$/, '') backtracks quadratically while processing the crafted redirect hostname. Synchronous regular-expression processing can block the Node.js event loop and cause denial of service. This issue is fixed in version 1.20.0.
NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.
Source analysis status: Awaiting Analysis
Weakness classifications: CWE-400 · CWE-1333
Original publisher date fields
published: 2026-09-28T18:17:19.100
lastModified: 2026-09-30T19:38:27.293
- Source published
- 28 Sep 2026 18:17:19 UTC
- Source modified
- 30 Sep 2026 19:38:27 UTC
- Observed here
- 25 Oct 2026 04:17:26 UTC
- Source terms
- NIST NVD usage terms; underlying source attribution retained
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS 4.0 · [email protected] · Secondary · 8.2 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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
osv · GHSA-mghh-pgcx-3jjj
Published## Summary Axios `shouldBypassProxy()` normalizes hostnames with `hostname.replace(/\.+$/, '')`. For a hostname shaped as many dots followed by a non-dot, the anchored regex can perform quadratic backtracking. Because axios re-evaluates proxy bypass rules for redirected requests, a malicious server can trigger this synchronous work through a crafted redirect `Location`. The issue affects Node.js applications that use environment proxy variables with `NO_PROXY` and allow redirects. ## Impact An attacker-controlled server can return a redirect whose hostname causes the axios process to spend significant CPU time in synchronous hostname normalization. During this time, the Node.js event loop is blocked and the application cannot handle other work on that thread. This is an availability-only issue. It does not disclose request data or modify requests. ## Affected Functionality Affected: - Node.js HTTP adapter. - Environment proxy handling through `HTTP_PROXY` or `HTTPS_PROXY`. - `NO_PROXY` or `no_proxy` set to a non-empty value. - Redirects followed by axios or `follow-redirects`. Not affected: - Browser adapters. - Requests with `proxy: false`. - Requests with no `NO_PROXY` value. - Requests with `maxRedirects: 0`, unless application code manually follows the malicious redirect and re-enters axios. ## Technical Details `lib/helpers/shouldBypassProxy.js` contains: ```js return unmapIPv4MappedIPv6(hostname.replace(/\.+$/, '')); ``` When the hostname is `"." * n + "a"`, the `$` anchor causes the regex engine to retry the dot run from many positions before it fails. `setProxy()` invokes `shouldBypassProxy(location)` after `getProxyForUrl(location)` returns a proxy, including on redirect hops via `beforeRedirects.proxy`. Local timing on axios `1.18.1` showed increasing cost for crafted hostnames: about 1 ms at 1000 dots, 6.9 ms at 3000 dots, and 34.5 ms at 6000 dots. The growth is consistent with the submitted quadratic claim while avoiding long-running payloads. ## Proof of Concept of Attack Constrained helper-level demonstration: ```js import shouldBypassProxy from 'axios/lib/helpers/shouldBypassProxy.js'; process.env.NO_PROXY = 'example.com'; shouldBypassProxy('http://' + '.'.repeat(6000) + 'a/'); ``` In the full adapter path, a malicious server can return that hostname in a `302 Location` header while the client has proxy environment variables and `NO_PROXY` configured. ## Workarounds Disable automatic redirects for requests to untrusted servers, or avoid environment proxy handling for those requests with `proxy: false` when appropriate. Operators can also avoid broad untrusted redirect-following in services where event-loop availability is critical. <details> <summary><h3>Original report</h3></summary> ### Summary shouldBypassProxy normalizes a host with hostname.replace(/\.+$/, ''). On a host of the shape <many dots><non-dot> (e.g. "." × 40000 + "a"), this anchored regex backtracks quadratically (O(N²)), synchronously starving the Node.js event loop. Because axios re-evaluates the proxy on every redirect using the new Location host, a malicious server can return a crafted 302 Location and freeze the client's event loop for seconds per redirect — a denial of service. ### Details - Affected code: lib/helpers/shouldBypassProxy.js → normalizeNoProxyHost: hostname.replace(/\.+$/, '') (one pass in 1.18.1). The open PR #11029 adds a second /\.+$/ pass in normalizeIPAddress, doubling the cost (not the origin). - Root cause: /\.+$/ is O(N²) on a long run of dots that is not at the end of the string — the $ anchor forces the engine to backtrack the entire dot-run from every start position. - Trust boundary (per THREATMODEL): the redirect Location is untrusted (T-2: "axios to network … redirect Location … untrusted"). The caller requests a benign URL; the malicious host arrives via the server's 302. This is not the T-1 caller-supplied-URL non-goal. - Call chain: setProxy(options, configProxy, location, isRedirect, …) (lib/adapters/http.js) → env-proxy branch → getProxyForUrl(location) returns a proxy → if (!shouldBypassProxy(location)) → normalizeNoProxyHost(parsed.hostname.toLowerCase()) runs /\.+$/. setProxy is re-invoked on the redirect hop with the untrusted Location; new URL() retains the long dot-run in .hostname. - Preconditions: proxy configured via environment (HTTP_PROXY/HTTPS_PROXY, trusted per THREATMODEL T-3, common in CI/containers/enterprise) + NO_PROXY set + redirects followed (default maxRedirects: 5). ### PoC Self-contained, no network — imports axios's own helper: // node poc.mjs (run next to an axios install) import sbp from './node_modules/axios/lib/helpers/shouldBypassProxy.js'; process.env.NO_PROXY = 'example.com'; for (const n of [5000, 10000, 20000, 40000]) { const url = 'http://' + '.'.repeat(n) + 'a/'; // arrives as an untrusted 302 Location host const t0 = process.hrtime.bigint(); sbp(url); // returns false (correct no-bypass) — but O(N^2) slow console.log(`N=${n}: ${(Number(process.hrtime.bigint()-t0)/1e6)|0} ms`); } // Measured on 1.18.1: N=5000 ~43ms, 10000 ~160ms, 20000 ~618ms, 40000 ~2499ms; benign host ~0.05ms. Driven through the real http-adapter __setProxy on the redirect path (setProxy(…, isRedirect=true)), a 10 ms timer fires 0 times during the ~2.4 s block at N=40000 — full event-loop starvation. ### Impact Denial of service (event-loop starvation) on any axios client that uses an environment proxy with NO_PROXY set and follows redirects, when a server it contacts returns a crafted redirect Location. No data exposure or RCE. Same impact class as the accepted DoS advisories GHSA-62hf-57xw-28j9 (toFormData recursion) and the maxContentLength response-size DoS. ### Suggested fix Replace the regex trailing-dot strip with a linear trim: let end = hostname.length; while (end > 0 && hostname.charCodeAt(end - 1) === 46 /* '.' */) end--; hostname = hostname.slice(0, end); Also drop the redundant second /\.+$/ pass in PR #11029's normalizeIPAddress. </details> ---
- Source published
- 30 Sep 2026 15:03:02 UTC
- Source modified
- 30 Sep 2026 15:15:04 UTC
- Observed here
- 24 Oct 2026 13:17:17 UTC
- Source terms
- GitHub Advisory Database · CC-BY-4.0
Original source record · Cite this exact observation · Complete original publisher JSON
This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.
CVSS_V4 · 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
Publisher rating · HIGH