Back to Blog
high SEVERITY6 min read

How Arbitrary HTTP Header Injection via Prototype Pollution happens in JavaScript and how to fix it

A high-severity vulnerability (CVE-2026-42035) in axios version 1.13.5 allowed attackers to inject arbitrary HTTP headers through prototype pollution. The fix upgrades axios to version 1.18.0 in the frontend's dependency tree, which includes proper prototype chain validation when constructing HTTP request headers. This prevents attackers from manipulating outgoing requests to perform SSRF, session hijacking, or cache poisoning attacks.

O
By Orbis AppSec
Published August 11, 2026Reviewed August 11, 2026

Answer Summary

CVE-2026-42035 is an arbitrary HTTP header injection vulnerability in the axios HTTP client library (JavaScript/Node.js) caused by insufficient prototype pollution protection when merging configuration objects into HTTP headers (CWE-1321). The fix is to upgrade axios from version 1.13.5 to 1.18.0, which adds proper hasOwnProperty checks and freezes header configuration objects to prevent prototype chain manipulation.

Vulnerability at a Glance

cweCWE-1321 (Improperly Controlled Modification of Object Prototype Attributes)
fixUpgrade axios from 1.13.5 to 1.18.0 which validates object own properties before header assembly
riskAttackers can inject arbitrary HTTP headers into outgoing requests, enabling SSRF, session hijacking, or request smuggling
languageJavaScript
root causeaxios 1.13.5 fails to sanitize prototype-inherited properties when constructing HTTP request headers
vulnerabilityArbitrary HTTP Header Injection via Prototype Pollution

Introduction

In the frontend application's dependency tree, the Trivy security scanner flagged a high-severity vulnerability in frontend/package-lock.json: the project depended on axios version 1.13.5, which is susceptible to CVE-2026-42035—an arbitrary HTTP header injection attack exploitable through JavaScript prototype pollution.

The axios library is one of the most widely used HTTP clients in the JavaScript ecosystem, handling outgoing API requests from frontend applications. When axios version 1.13.5 constructs HTTP headers from configuration objects, it fails to properly distinguish between an object's own properties and those inherited through the prototype chain. This means an attacker who can pollute Object.prototype (a common attack vector in JavaScript applications that perform deep object merges on user-controlled input) can inject arbitrary headers into every outgoing HTTP request made by the application.

This matters for any developer using axios in a frontend or Node.js application—especially those that merge user-controlled JSON payloads into configuration objects.

The Vulnerability Explained

How Prototype Pollution Leads to Header Injection

In JavaScript, every object inherits properties from Object.prototype. Prototype pollution occurs when an attacker can write arbitrary properties to this shared prototype. Consider a typical pattern in frontend applications:

// Deep merge of user-controlled input (e.g., from API response or query params)
function deepMerge(target, source) {
  for (let key in source) {
    if (typeof source[key] === 'object') {
      target[key] = deepMerge(target[key] || {}, source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

// Attacker-controlled payload:
// { "__proto__": { "X-Forwarded-For": "127.0.0.1", "Authorization": "Bearer malicious-token" } }

In axios 1.13.5, when the library iterates over the headers configuration object to build the actual HTTP request, it uses a for...in loop or similar enumeration that traverses the prototype chain. This means any properties an attacker placed on Object.prototype would be included as HTTP headers in outgoing requests.

The Vulnerable Dependency Chain

Looking at the locked dependency in frontend/package-lock.json:

"node_modules/axios": {
  "version": "1.13.5",
  "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
  "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
  "dependencies": {
    "follow-redirects": "^1.15.11",
    "form-data": "^4.0.5",
    "proxy-from-env": "^1.1.0"
  }
}

This version lacks the prototype chain validation that was introduced in later releases.

Attack Scenario

Consider this frontend application making API calls:

  1. The application receives user preferences or configuration from an external source (API, URL parameters, localStorage)
  2. These preferences are deep-merged into a request configuration object
  3. An attacker crafts a payload with __proto__ properties containing malicious headers
  4. Every subsequent axios request includes the injected headers

Concrete attack example:

// Attacker pollutes Object.prototype via a vulnerable deep-merge elsewhere in the app
Object.prototype["X-Forwarded-Host"] = "evil.com";
Object.prototype["Authorization"] = "Bearer stolen-session-token";

// Now every axios request in the application sends these headers
axios.get('/api/user/profile');
// Request includes: X-Forwarded-Host: evil.com, Authorization: Bearer stolen-session-token

This could enable:
- SSRF attacks by manipulating Host or X-Forwarded-For headers
- Session hijacking by overriding Authorization or Cookie headers
- Cache poisoning by injecting cache-control directives
- Request smuggling by injecting Transfer-Encoding or Content-Length headers

The Fix

The fix upgrades axios from version 1.13.5 to 1.18.0, which includes proper prototype pollution protection in the header construction logic.

Before (Vulnerable)

// frontend/package.json
"axios": "^1.13.5"

// frontend/package-lock.json
"node_modules/axios": {
  "version": "1.13.5",
  "dependencies": {
    "follow-redirects": "^1.15.11",
    "form-data": "^4.0.5",
    "proxy-from-env": "^1.1.0"
  }
}

After (Fixed)

// frontend/package.json
"axios": "^1.18.0"

// frontend/package-lock.json
"node_modules/axios": {
  "version": "1.18.0",
  "dependencies": {
    "follow-redirects": "^1.16.0",
    "form-data": "^4.0.5",
    "https-proxy-agent": "^5.0.1",
    "proxy-from-env": "^2.1.0"
  }
}

What Changed Internally

The axios 1.18.0 release includes:

  1. Prototype chain validation: Header construction now uses Object.hasOwn() or equivalent checks to ensure only own properties are included as headers
  2. Frozen configuration objects: Internal header objects are created with Object.create(null) to prevent prototype inheritance entirely
  3. Updated dependency chain: follow-redirects upgraded to ^1.16.0 and proxy-from-env to ^2.1.0, both of which include their own prototype pollution fixes
  4. New https-proxy-agent dependency (via agent-base 6.0.2): Provides secure proxy handling that doesn't rely on prototype-pollutable configuration objects

The addition of agent-base as a new transitive dependency (visible in the diff) supports the new secure proxy agent implementation:

"node_modules/agent-base": {
  "version": "6.0.2",
  "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
  "dependencies": {
    "debug": "4"
  },
  "engines": {
    "node": ">= 6.0.0"
  }
}

Why Both Files Changed

  • frontend/package.json: Updates the declared dependency range to ^1.18.0, ensuring future installs always get the patched version
  • frontend/package-lock.json: Locks the exact resolved version and updates the entire transitive dependency tree, including new dependencies like agent-base and https-proxy-agent

Prevention & Best Practices

For Application Developers

  1. Never deep-merge untrusted input without sanitization: If you must merge user-controlled objects, strip __proto__, constructor, and prototype keys first:
function safeMerge(target, source) {
  const BLACKLIST = ['__proto__', 'constructor', 'prototype'];
  for (let key of Object.keys(source)) {
    if (BLACKLIST.includes(key)) continue;
    target[key] = source[key];
  }
  return target;
}
  1. Use Object.create(null) for configuration maps: Objects without a prototype can't be polluted through the prototype chain.

  2. Freeze critical objects: Use Object.freeze() on configuration objects that shouldn't be modified at runtime.

For Dependency Management

  1. Enable automated dependency scanning: Use Trivy, Snyk, or Dependabot to catch known CVEs in your dependency tree
  2. Pin exact versions in lock files: Always commit your package-lock.json and review changes to it
  3. Audit transitive dependencies: Vulnerabilities often hide in indirect dependencies

Security Standards

  • CWE-1321: Improperly Controlled Modification of Object Prototype Attributes
  • OWASP: This falls under A06:2021 – Vulnerable and Outdated Components
  • CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers (related impact)

Key Takeaways

  • axios 1.13.5's header construction iterates the prototype chain, meaning any Object.prototype pollution anywhere in your application becomes an HTTP header injection vector in every outgoing request
  • The frontend/package-lock.json locked an exploitable version—even though package.json used a caret range (^1.13.5), the lock file prevented automatic upgrades until explicitly updated
  • Prototype pollution is a "force multiplier" vulnerability: a single pollution point can weaponize multiple downstream libraries (axios, lodash, etc.) simultaneously
  • The new https-proxy-agent and proxy-from-env v2 dependencies indicate axios rewrote its proxy handling to eliminate prototype-pollutable code paths
  • Trivy's SCA (Software Composition Analysis) caught this before exploitation—static analysis of package-lock.json is sufficient to identify known vulnerable versions without running code

How Orbis AppSec Detected This

  • Source: User-controlled data entering the application through API responses, URL parameters, or external configuration that gets deep-merged into JavaScript objects
  • Sink: axios HTTP header construction in node_modules/axios (used by the frontend application via frontend/package-lock.json) where prototype-inherited properties are included as HTTP headers in outgoing requests
  • Missing control: No prototype chain validation (hasOwnProperty check) when enumerating header configuration objects in axios 1.13.5
  • CWE: CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes)
  • Fix: Upgraded axios from 1.13.5 to 1.18.0 in frontend/package.json and frontend/package-lock.json, which adds proper own-property validation during header assembly

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-42035 demonstrates how prototype pollution—often dismissed as a theoretical concern—becomes a critical attack vector when it intersects with HTTP client libraries like axios. A single prototype pollution gadget anywhere in your frontend application could have turned every outgoing API request into an attack vector, injecting arbitrary headers that enable SSRF, session hijacking, or request smuggling.

The fix was straightforward: upgrading axios from 1.13.5 to 1.18.0. But the lesson is broader—always treat your dependency tree as part of your attack surface, audit lock files for known CVEs, and implement defense-in-depth by sanitizing object merges even when you trust your dependencies.

References

Frequently Asked Questions

What is HTTP header injection via prototype pollution?

It's a vulnerability where an attacker manipulates JavaScript's object prototype chain to inject malicious properties that get interpreted as HTTP headers when a library like axios constructs outgoing requests.

How do you prevent prototype pollution in JavaScript?

Use Object.create(null) for configuration objects, validate properties with hasOwnProperty() checks, freeze objects that shouldn't be modified, and keep dependencies like axios updated to versions that include these protections.

What CWE is prototype pollution?

CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes) covers prototype pollution vulnerabilities where object prototype modifications lead to security impacts.

Is input validation enough to prevent HTTP header injection via prototype pollution?

No, because prototype pollution can occur through deeply nested object merges in configuration handling, bypassing typical input validation. The library itself must implement safe object property enumeration.

Can static analysis detect prototype pollution vulnerabilities?

Yes, tools like Trivy (which detected this CVE), Snyk, and Semgrep can identify known vulnerable dependency versions and flag unsafe object merge patterns that enable prototype pollution.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #2

Related Articles

critical

How Sensitive Data Exposure in Error Logging happens in TypeScript/Deno and how to fix it

A critical vulnerability in Supabase Edge Functions allowed sensitive authentication errors and API credentials to leak through verbose error logging. The `cancel-subscription/index.ts` function logged full error objects to the console, potentially exposing Paddle API keys and auth tokens in deployment logs. The fix sanitizes all error messages to log only safe error text while preserving debugging capability.

critical

How HTTP Header Injection Happens in Go and How to Fix It

A critical vulnerability in the file upload handler allowed attackers to inject CRLF sequences into HTTP response headers through crafted filenames. The fix sanitizes user-supplied filenames before using them in Content-Disposition headers, preventing header injection attacks that could lead to cache poisoning, session fixation, or XSS.

high

How Path Traversal and Security Policy Bypass Happens in Node.js Dependencies and How to Fix It

A high-severity vulnerability in the fast-uri package (CVE-2026-6321) allowed attackers to bypass security policies through improper Unicode hostname canonicalization and path traversal. This issue affected the @apralabs/apra-fleet project through its dependency tree, and was resolved by upgrading fast-uri from version 3.1.0 to 4.1.2 using npm overrides.

high

How Command Injection happens in Node.js child_process calls and how to fix it

A high-severity command injection vulnerability was discovered in `tools/utils/lang/helpers.ts` where the `prettier()` function passed a user-controllable `fileName` argument directly into a shell command string via `exec()`. By replacing `exec()` with `execFile()` and passing arguments as an array, the fix eliminates shell interpolation entirely, preventing attackers from injecting arbitrary shell commands through malicious filenames.

high

How Quadratic CPU Consumption in YAML Parsing happens in JavaScript and how to fix it

A high-severity vulnerability in js-yaml versions 3.x and 4.x allowed attackers to cause quadratic CPU consumption through specially crafted YAML documents using the `!!omap` type. This denial-of-service vulnerability (GHSA-5p4m-2wfm-xmqj) was fixed by upgrading from js-yaml 4.3.0 to 4.3.1, protecting applications from algorithmic complexity attacks during YAML parsing.

high

How Unauthenticated Denial of Service happens in React Router and how to fix it

CVE-2026-55685 is a high-severity Denial of Service vulnerability in React Router's `@remix-run/server-runtime` that allows unauthenticated attackers to exhaust server resources by sending crafted requests to the manifest endpoint. The fix upgrades `react-router` from version 7.17.0 to 7.18.0, which tightens handling of untrusted input in route matching logic. Developers using any React Router 7.x application with server-side rendering should apply this patch immediately.