Back to Blog
high SEVERITY8 min read

How HTTP Transport Hijacking via Prototype Pollution happens in JavaScript and how to fix it

CVE-2026-42033 is a high-severity prototype pollution vulnerability in axios that allows attackers to hijack the HTTP transport layer used by the library. The deltamod project was running axios 1.14.0, which lacked the hardened transport configuration introduced in 1.18.0 — including an explicit `https-proxy-agent` dependency and an upgraded `follow-redirects` floor. Upgrading to axios 1.18.0 closes the attack surface by ensuring that object prototype manipulation cannot silently redirect or int

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

Answer Summary

CVE-2026-42033 is a high-severity prototype pollution vulnerability (CWE-1321) in the axios JavaScript HTTP client that enables HTTP Transport Hijacking. In versions prior to 1.15.1/1.18.0, an attacker who can influence JavaScript object properties can pollute `Object.prototype` to override axios's internal transport adapter, silently redirecting or intercepting all outbound HTTP requests made by the application. The fix is to upgrade axios to 1.18.0 (or 1.15.1 for the 0.x branch), which introduces explicit `https-proxy-agent` handling and raises the `follow-redirects` floor to `^1.16.0`, preventing prototype-inherited properties from substituting the legitimate transport agent.

Vulnerability at a Glance

cweCWE-1321
fixUpgrade axios from 1.14.0 to 1.18.0; adds explicit https-proxy-agent and raises follow-redirects floor to ^1.16.0
riskAttacker can redirect or intercept all outbound HTTP/HTTPS requests made by the application
languageJavaScript / Node.js
root causeaxios resolved its HTTP transport adapter from object properties without guarding against prototype-inherited values
vulnerabilityHTTP Transport Hijacking via Prototype Pollution

How HTTP Transport Hijacking via Prototype Pollution Happens in JavaScript and How to Fix It


The Problem in Plain Sight: A Dependency That Became a Liability

The package-lock.json file in the deltamod project locked axios at version 1.14.0. On the surface, that looks unremarkable — a pinned dependency doing its job. But Trivy's static analysis flagged it as CVE-2026-42033, a high-severity vulnerability that could allow an attacker to silently redirect every outbound HTTP request the application makes. The fix was a version bump, but understanding why the old version was dangerous — and exactly what changed — is worth a close look.


The Vulnerability Explained

What Is Prototype Pollution?

JavaScript's prototype chain means that almost every object in a Node.js runtime ultimately inherits from Object.prototype. If an attacker can write an arbitrary key to Object.prototype, every plain object in the process will appear to have that key as an "own-like" property — unless the code explicitly guards against inherited values.

// Attacker-controlled input triggers this somewhere in the dependency tree:
Object.prototype.adapter = maliciousTransportAgent;

// Now, inside axios's transport resolution:
const config = {};
console.log(config.adapter); // → maliciousTransportAgent  ← NOT the real axios adapter

How Axios 1.14.0 Was Affected

In axios versions before the fix, the library resolved its HTTP transport adapter by reading the adapter (and related transport configuration) properties from the merged request config object. Because this lookup did not use Object.prototype.hasOwnProperty checks or Object.create(null) maps, a polluted prototype could inject a foreign value into the transport resolution path.

The vulnerable package-lock.json entry looked like this:

"node_modules/axios": {
  "version": "1.14.0",
  "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz",
  "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==",
  "dependencies": {
    "follow-redirects": "^1.15.11",
    "form-data": "^4.0.5",
    "proxy-from-env": "^2.1.0"
  }
}

Two things stand out:

  1. No https-proxy-agent — there is no explicit, version-pinned HTTPS proxy agent. The transport layer for HTTPS connections was therefore resolved more loosely.
  2. follow-redirects floor at ^1.15.11 — this floor is below the version that introduced hardened prototype-pollution defenses in redirect handling.

The Attack Scenario

Imagine deltamod is a desktop application that fetches update manifests or patch metadata over HTTPS. An attacker who can influence any JavaScript object deserialization in the same process (e.g., via a malicious plugin, a crafted TOML config loaded through @std/toml, or a compromised transitive dependency) could execute:

// Somewhere in a malicious or compromised dependency:
const payload = JSON.parse('{"__proto__": {"adapter": "http"}}');
// Or more directly:
Object.prototype.httpsAgent = new http.Agent({ /* attacker proxy */ });

Once Object.prototype is polluted, the next time deltamod calls:

axios.get('https://update-server.example.com/manifest.json')

…axios's internal config merge produces an object that appears to have httpsAgent set to the attacker's proxy. All HTTPS traffic is now routed through that proxy, enabling:

  • Credential theft — any Authorization headers or tokens in requests are exposed.
  • Response tampering — the attacker can serve a malicious update manifest, potentially triggering a malicious binary download.
  • Data exfiltration — request bodies containing user data are intercepted silently.

For deltamod specifically — a tool that downloads and applies binary patches — a hijacked transport could mean the application installs attacker-controlled files.


The Fix

What Changed in package-lock.json

The pull request upgrades axios from 1.14.0 to 1.18.0. Here is the exact diff for the axios entry:

Before:

"node_modules/axios": {
  "version": "1.14.0",
  "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz",
  "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==",
  "dependencies": {
    "follow-redirects": "^1.15.11",
    "form-data": "^4.0.5",
    "proxy-from-env": "^2.1.0"
  }
}

After:

"node_modules/axios": {
  "version": "1.18.0",
  "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.0.tgz",
  "integrity": "sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw==",
  "dependencies": {
    "follow-redirects": "^1.16.0",
    "form-data": "^4.0.5",
    "https-proxy-agent": "^5.0.1",
    "proxy-from-env": "^2.1.0"
  }
},
"node_modules/axios/node_modules/agent-base": {
  "version": "6.0.2",
  "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
  "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
  "dependencies": {
    "debug": "4"
  },
  "engines": {
    "node": ">= 6.0.0"
  }
}

Why Each Change Matters

Change Security Significance
follow-redirects floor raised from ^1.15.11^1.16.0 follow-redirects 1.16.0 introduced its own prototype-pollution guards in redirect URL resolution, closing a secondary vector
https-proxy-agent: ^5.0.1 added as an explicit dependency axios now resolves the HTTPS transport agent from a declared, integrity-checked package rather than from a loosely inherited property
New agent-base@6.0.2 sub-dependency pinned Provides the underlying socket abstraction that https-proxy-agent uses; having it explicitly pinned prevents prototype-inherited agent-base substitution
package.json axios range updated from ^1.12.0^1.18.0 Ensures future npm install runs never resolve back to a vulnerable version

The Core Security Improvement

By making https-proxy-agent an explicit, integrity-verified dependency, axios 1.18.0 no longer needs to fall back to prototype-chain property lookup when constructing its HTTPS transport. The agent is imported directly:

// Conceptual representation of the fix inside axios internals:
// Before (vulnerable): agent resolved from config object — pollutable
const agent = config.httpsAgent; // could come from Object.prototype

// After (fixed): agent resolved from explicit, imported module
const { HttpsProxyAgent } = require('https-proxy-agent'); // explicit import
const agent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined;

This means even if Object.prototype.httpsAgent is polluted, axios ignores it in favor of the explicitly constructed agent.


Prevention & Best Practices

1. Guard Against Prototype Pollution in Your Own Code

When merging configuration objects, never use plain {} as a base if the source could be attacker-influenced:

// Vulnerable
const config = Object.assign({}, userInput, defaults);

// Safer
const config = Object.assign(Object.create(null), userInput, defaults);
// Or use structured clone:
const config = structuredClone(defaults);
Object.assign(config, sanitize(userInput));

2. Validate Own-Property Access

When reading security-sensitive properties from config objects:

// Vulnerable
const adapter = config.adapter;

// Safe
const adapter = Object.prototype.hasOwnProperty.call(config, 'adapter')
  ? config.adapter
  : defaultAdapter;

3. Pin and Audit Your Dependency Tree Regularly

The deltamod package.json had "axios": "^1.12.0" — a range that allowed any 1.x minor. While semver ranges are convenient, they mean a npm install on a fresh machine could resolve to any version in that range. After this fix, the range is ^1.18.0, which ensures the minimum resolved version is always patched.

# Run regularly in CI:
npm audit
npx better-npm-audit audit

# Or use Trivy directly:
trivy fs --scanners vuln package-lock.json

4. Use --ignore-scripts and Subresource Integrity

npm ci --ignore-scripts

This prevents malicious postinstall scripts from polluting prototypes during installation.

5. Consider --frozen-lockfile in Production

npm ci  # always uses package-lock.json exactly; never resolves ranges

Security Standards Reference

  • CWE-1321: Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
  • OWASP A06:2021 – Vulnerable and Outdated Components
  • OWASP A08:2021 – Software and Data Integrity Failures

Key Takeaways

  • package-lock.json locking axios@1.14.0 was the direct root cause — a version range of ^1.12.0 in package.json silently allowed a vulnerable version to be installed for months.
  • The absence of an explicit https-proxy-agent dependency in axios 1.14.0 meant HTTPS transport resolution was vulnerable to prototype-inherited property injection — a subtle but critical gap.
  • Raising the follow-redirects floor from ^1.15.11 to ^1.16.0 closes a secondary prototype-pollution vector in redirect URL handling that would otherwise remain open even after the primary fix.
  • For deltamod specifically, the risk was concrete: a hijacked transport could have caused the application to download and apply attacker-controlled binary patches, leading to full system compromise.
  • Trivy's static analysis of package-lock.json caught this before exploitation — demonstrating the value of scanning lock files, not just source code.

How Orbis AppSec Detected This

  • Source: The tainted data entry point is any JavaScript object deserialization or merge operation within the deltamod process (or its dependency tree) that processes attacker-influenced input without prototype-pollution guards.
  • Sink: axios's internal transport adapter resolution, which reads httpsAgent and adapter from the merged request config object — properties that can be inherited from a polluted Object.prototype.
  • Missing control: axios 1.14.0 lacked an explicit https-proxy-agent import and did not perform hasOwnProperty checks before using transport-related config properties, allowing prototype-inherited values to substitute the legitimate transport agent.
  • CWE: CWE-1321 — Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')
  • Fix: Upgraded axios from 1.14.0 to 1.18.0 in package-lock.json, adding an explicit https-proxy-agent@^5.0.1 dependency and raising the follow-redirects floor to ^1.16.0.

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-42033 is a reminder that prototype pollution is not just a theoretical concern — in a library as widely used as axios, it translates directly into HTTP transport hijacking that can silently redirect every outbound request your application makes. For deltamod, a tool that downloads and applies binary patches, that could have meant the difference between a legitimate update and a full system compromise.

The fix is straightforward: upgrade axios to 1.18.0. But the broader lesson is architectural — explicit dependency declarations, integrity hashes, and own-property guards are the layers that prevent prototype pollution from becoming transport hijacking. Keep your lock files audited, your dependency ranges tight, and your CI pipelines running npm audit and Trivy on every commit.


References

Frequently Asked Questions

What is HTTP Transport Hijacking via Prototype Pollution?

It is an attack where an adversary pollutes JavaScript's Object.prototype with a crafted property that axios reads when selecting its HTTP transport adapter, causing all outbound requests to be routed through an attacker-controlled agent instead of the legitimate one.

How do you prevent prototype pollution in JavaScript?

Use Object.create(null) for configuration maps, validate that resolved properties are own-properties (hasOwnProperty), freeze critical prototype chains, and keep HTTP client libraries patched to versions that perform these checks internally.

What CWE is prototype pollution?

Prototype pollution is classified as CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes).

Is input sanitization enough to prevent prototype pollution in axios?

Not on its own. The vulnerability exists inside axios's transport resolution logic, so sanitizing application-level user input does not protect against a malicious package or indirect dependency that has already polluted the prototype. Upgrading axios is required.

Can static analysis detect prototype pollution vulnerabilities?

Yes. Tools like Trivy (which flagged this issue), Semgrep, and Snyk can identify known-vulnerable package versions in package-lock.json and detect prototype pollution patterns in source code.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #70

Related Articles

high

How Arbitrary Code Execution via Template Imports happens in JavaScript and how to fix it

CVE-2026-4800 is a high-severity arbitrary code execution vulnerability in lodash-es versions prior to 4.18.0, triggered through untrusted input passed to lodash's template engine. The fix upgrades lodash-es from 4.17.23 to 4.18.1 using a pnpm override, ensuring all transitive dependents pick up the patched version. This is a concrete reminder that even utility libraries like lodash can become critical attack surfaces when they process user-controlled input.

high

How EL Injection happens in Java JSF applications and how to fix it

A high-severity Expression Language (EL) injection vulnerability was discovered and fixed in `PrimeFacesResourceProcessor.java`, a JSF phase listener responsible for resolving the PrimeFaces theme configuration. The flaw allowed a dynamically sourced theme parameter value to be passed directly into an EL expression factory without first verifying whether the value was actually an EL expression or plain text. The fix introduces explicit input branching that separates EL expressions from literal s

medium

How XML External Entity (XXE) Injection happens in Python and how to fix it

A medium-severity XML External Entity (XXE) vulnerability was discovered in `listKeyboardLayouts.py`, where Python's native `xml.etree.ElementTree` library was used to parse XML data. This library is susceptible to XXE attacks, which can allow attackers to read local files, perform server-side request forgery, or cause denial of service. The fix replaces the unsafe import with `defusedxml.ElementTree`, a drop-in hardened alternative recommended by the Python documentation itself.

high

How Prototype Pollution happens in Node.js async libraries and how to fix it

A high-severity prototype pollution vulnerability (CVE-2021-43138) was discovered in the `async` npm package versions prior to 3.2.2, affecting the `node-red-contrib-opcua` project. By exploiting crafted input passed through async's utility functions, an attacker could corrupt JavaScript's `Object.prototype`, potentially enabling privilege escalation or remote code execution. Upgrading `async` from `3.2.1` to `^3.2.2` in both `package.json` and `package-lock.json` eliminates the attack surface e

high

How SQL Injection happens in Python BigQuery connectors and how to fix it

A high-severity SQL injection vulnerability was discovered in a BigQuery connector's query-building logic, where Python f-strings interpolated user-controlled identifiers—project_id, dataset_id, table_id, and timestamp_column—directly into SQL without validation. An attacker with control over connector configuration could inject arbitrary BigQuery SQL, including destructive statements. The fix introduces strict allowlist-based identifier validation using compiled regular expressions before any S

high

How Path Traversal happens in PostCSS Source Map Loading and how to fix it

A path traversal vulnerability in PostCSS versions before 8.5.18 allowed malicious `sourceMappingURL` comments in CSS files to trick PostCSS into loading arbitrary `.map` files from the filesystem. The fix upgrades PostCSS from 8.5.15 to 8.5.18 in `frontend/package-lock.json` and pins the version via an override in `frontend/package.json`, closing the file disclosure vector before it could be chained with other weaknesses.