PT-2026-103485 · Npm · Axios
CVE-2026-101899
·
Publicado
2026-09-30
·
Atualizado
2026-09-30
CVSS v4.0
6.9
Média
| Vetor | AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:N/SA:N |
Summary
Axios supports proxy environment variables and evaluates
NO PROXY exclusions in the Node.js adapter. CIDR-form NO PROXY entries such as 127.0.0.0/8, 10.0.0.0/8, or 169.254.169.254/32 are not interpreted as IP ranges. As a result, a request to an IP address inside a configured CIDR exclusion can still be sent through the configured proxy.This affects deployments that rely on CIDR notation to keep loopback, private, Kubernetes, CI, or cloud metadata traffic away from proxy infrastructure.
Impact
If the configured proxy is outside the intended trust boundary, requests that operators expected to bypass the proxy may be exposed to it. For plaintext HTTP targets, the proxy can see and modify URLs, headers, and bodies. For HTTPS targets, the proxy still observes connection metadata and may receive CONNECT requests that policy expected to avoid.
This is a proxy exclusion bypass, not arbitrary proxy injection by itself.
Affected Functionality
Affected:
- Node.js adapter proxy environment handling.
HTTP PROXY,HTTPS PROXY,NO PROXY, or lowercase equivalents.- CIDR entries in
NO PROXY.
Not affected:
- Exact host or exact IP
NO PROXYentries where axios matching succeeds. - Requests configured with
proxy: false. - Browser adapters.
Technical Details
lib/helpers/shouldBypassProxy.js parses each NO PROXY entry into a host and optional port, normalizes hostnames, and then compares exact hostnames, suffix entries, wildcard-prefix entries, and loopback equivalents. It does not parse CIDR notation.Local verification on axios
1.18.1:js
process.env.NO PROXY = '127.0.0.0/8';
shouldBypassProxy('http://127.0.0.1:1234/'); // falseThe expected result for CIDR-aware bypass policy is
true.Proof of Concept of Attack
Constrained local demonstration:
- Set
HTTP PROXY=http://127.0.0.1:<proxy-port>. - Set
NO PROXY=127.0.0.0/8. - Request
http://127.0.0.1:<internal-port>/metadata. - Observe that axios sends the request through the proxy instead of directly to the internal listener.
Workarounds
Use exact host or IP entries in
NO PROXY for sensitive destinations until CIDR matching is fixed, for example 127.0.0.1,localhost,169.254.169.254. For individual requests that must not use a proxy, set proxy: false.Original report
Summary
Axios 1.17.0 honors
HTTP PROXY / HTTPS PROXY and supports NO PROXY host exclusions, but CIDR-form NO PROXY entries such as 127.0.0.0/8 are not treated as network ranges. As a result, requests to IPs covered by a configured CIDR exclusion may still be sent through the configured proxy.In the attached PoC, a request to
127.0.0.1 is sent through HTTP PROXY despite NO PROXY=127.0.0.0/8.This can cause proxy exclusion bypass in environments where operators use CIDR notation to exclude loopback, private, internal, Kubernetes, CI, or cloud metadata address ranges from proxying.
Details
Axios supports proxy environment variables, including
HTTP PROXY / HTTPS PROXY and NO PROXY-style exclusions. Axios’s threat model treats environment proxy handling as security-relevant and lists NO PROXY as a mitigation for proxy environment variable hijack, including hardening for CIDR ranges, IPv6 literals, and wildcard patterns. See: https://github.com/axios/axios/blob/a8e4f13aeecc45a3b8fab3ecfd9ddb5d70fb772b/THREATMODEL.md#t-r9-proxy-environment-variable-hijackThe issue is that CIDR-form
NO PROXY entries are not interpreted as network ranges. For example:text
NO PROXY=127.0.0.0/8
HTTP PROXY=http://127.0.0.1:<proxy-port>
Target URL=http://127.0.0.1:<internal-port>/metadataSince
127.0.0.1 is inside 127.0.0.0/8, an operator may reasonably expect Axios to bypass the proxy for this request. Instead, Axios sends the request through HTTP PROXY.This appears to affect the proxy bypass decision path used for
NO PROXY / no proxy handling. The relevant behavior is in Axios's Node proxy handling and NO PROXY evaluation logic, including the shouldBypassProxy helper introduced for no proxy hostname normalization and bypass checks.The issue is not that Axios ignores
NO PROXY entirely. Exact host exclusions work. The issue is specifically that CIDR-form exclusions are silently treated as non-matching host/domain tokens rather than as network ranges, causing the request to be proxied.This is security-relevant because CIDR notation is commonly used in container, CI, enterprise proxy, and cloud environments for ranges such as:
text
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.169.254/32If operators rely on those entries to prevent internal or metadata-style requests from traversing a proxy, Axios may violate that expectation.
PoC
js
import http from 'http';
import axios from 'axios';
function listen(server, host) {
return new Promise((resolve, reject) => {
server.once('error', reject);
server.listen(0, host, () => resolve(server.address().port));
});
}
function close(server) {
return new Promise((resolve) => server.close(resolve));
}
let proxyHits = 0;
let internalHits = 0;
const internal = http.createServer((req, res) => {
internalHits += 1;
res.writeHead(200, { 'content-type': 'text/plain' });
res.end(`internal service saw ${req.url}`);
});
const proxy = http.createServer((req, res) => {
proxyHits += 1;
res.writeHead(200, { 'content-type': 'text/plain' });
res.end(`proxy saw request for ${req.url}`);
});
const internalHost = process.env.POC INTERNAL HOST || '127.0.0.2';
const proxyHost = process.env.POC PROXY HOST || '127.0.0.1';
let internalPort;
let proxyPort;
try {
internalPort = await listen(internal, internalHost);
proxyPort = await listen(proxy, proxyHost);
} catch (error) {
console.error('Failed to bind local PoC servers.');
console.error('On some systems 127.0.0.2 is unavailable; try:');
console.error(' POC INTERNAL HOST=127.0.0.1 node poc-no-proxy-cidr-axios.mjs');
console.error('');
throw error;
}
const targetUrl = `http://${internalHost}:${internalPort}/metadata`;
const proxyUrl = `http://${proxyHost}:${proxyPort}`;
const noProxy = process.env.POC NO PROXY || '127.0.0.0/8';
process.env.http proxy = proxyUrl;
process.env.HTTP PROXY = proxyUrl;
process.env.no proxy = noProxy;
process.env.NO PROXY = noProxy;
console.log('Axios NO PROXY CIDR full axios network PoC');
console.log(`axios VERSION=${axios.VERSION || 'unknown'}`);
console.log(`NO PROXY=${process.env.no proxy}`);
console.log(`HTTP PROXY=${process.env.http proxy}`);
console.log(`Target URL=${targetUrl}`);
console.log('');
try {
const response = await axios.get(targetUrl, {
timeout: 2000,
});
console.log(`Response=${response.data}`);
console.log(`Proxy hits=${proxyHits}`);
console.log(`Internal direct hits=${internalHits}`);
console.log('');
if (proxyHits > 0 && internalHits === 0) {
console.log(`POC RESULT: axios sent the target through the proxy with NO PROXY=${noProxy}.`);
} else if (proxyHits === 0 && internalHits > 0) {
console.log(`POC RESULT: axios bypassed the proxy with NO PROXY=${noProxy}.`);
} else {
console.log('POC RESULT: mixed/ambiguous routing; inspect counts above.');
}
} finally {
delete process.env.http proxy;
delete process.env.HTTP PROXY;
delete process.env.no proxy;
delete process.env.NO PROXY;
await close(proxy);
await close(internal);
}Run the failing CIDR case:
bash
POC INTERNAL HOST=127.0.0.1 node poc-no-proxy-cidr-axios.mjsObserved:
text
Axios NO PROXY CIDR full axios network PoC
axios VERSION=1.17.0
NO PROXY=127.0.0.0/8
HTTP PROXY=http://127.0.0.1:34315
Target URL=http://127.0.0.1:43993/metadata
Response=proxy saw request for http://127.0.0.1:43993/metadata
Proxy hits=1
Internal direct hits=0
POC RESULT: axios sent the target through the proxy with NO PROXY=127.0.0.0/8.Control
Axios does honor exact IP
NO PROXY entries:bash
POC INTERNAL HOST=127.0.0.1 POC NO PROXY=127.0.0.1 node poc-no-proxy-cidr-axios.mjsExpected:
text
NO PROXY=127.0.0.1
Response=internal service saw /metadata
Proxy hits=0
Internal direct hits=1
POC RESULT: axios bypassed the proxy with NO PROXY=127.0.0.1.This shows the issue is not that
NO PROXY is ignored entirely. The bypass failure is specific to CIDR-form entries such as 127.0.0.0/8.Impact
This is a proxy exclusion bypass caused by unsupported CIDR matching in
NO PROXY.The impact is configuration-dependent. It affects Axios users in Node.js environments who rely on proxy environment variables and configure
NO PROXY using CIDR notation to exclude internal, loopback, private, Kubernetes, CI, or cloud metadata ranges.Potentially impacted environments include:
- CI/CD runners with globally injected
HTTP PROXY/HTTPS PROXY. - Containers inheriting proxy variables from the host or orchestrator.
- Kubernetes workloads using
NO PROXYfor cluster-internal service ranges. - Enterprise networks using HTTP proxies with internal network exclusions.
- Cloud workloads relying on
NO PROXYto keep metadata or internal service requests off proxy infrastructure.
If a configured proxy is compromised, attacker-controlled, overly broad, or outside the intended trust boundary, requests that operators expected to stay direct may instead be exposed to that proxy. This may expose request URLs, internal hostnames, paths, headers, or credentials depending on application behavior.
This should not be characterized as arbitrary proxy injection by itself. The issue is that Axios silently fails to enforce common CIDR-form proxy exclusions, which can undermine proxy bypass policy and defense-in-depth assumptions.
Correção
Protection Mechanism Failure
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾
Enumeração de Fraquezas
Identificadores relacionados
Produtos afetados
Axios