In March 2023, a security vulnerability (CVE-2023-26920) was discovered in the popular fast-xml-parser library (before version 4.1.2). This flaw allows an attacker to exploit prototype pollution by using the special __proto__ property in XML data. If you use this parser in your Node.js or JavaScript web apps, your software may be at risk.

This post will break down:

1. What is Prototype Pollution?

Prototype pollution is a security flaw unique to JavaScript. In JavaScript, every object “inherits” properties from its prototype. If an attacker can inject properties into Object.prototype, they can change how every object behaves in your app. Very bad things can happen — such as bypassing security checks, messing with app logic, and potentially running arbitrary code.

2. About fast-xml-parser

fast-xml-parser is a popular and fast XML-to-JSON converter. You find it everywhere — web backends, server utilities, and more. If you take user-supplied XML and parse it with fast-xml-parser, you might be at risk.

3. What’s the Vulnerability? (CVE-2023-26920)

The bug in brief:
fast-xml-parser accepted XML elements with the key __proto__. When converted to JSON, these keys became properties on the parsed objects. If your code then merges or copies such objects into the global context (e.g., through libraries like lodash), the __proto__ key could overwrite the global Object.prototype, polluting all objects!

Example problem

<root>
  <__proto__>
    <admin>true</admin>
  </__proto__>
</root>

After parsing, this produces

{
  root: {
    __proto__: {
      admin: "true"
    }
  }
}

Suppose you have a Node.js server that parses user-supplied XML

const fastXmlParser = require('fast-xml-parser');

const xml = `<root>
  <__proto__>
    <isAdmin>true</isAdmin>
  </__proto__>
</root>`;

const parsed = fastXmlParser.parse(xml);
console.log(parsed); 
console.log({}.isAdmin);     // Might be undefined here

// Let's pollute Object.prototype
Object.assign({}, parsed.root);

console.log({}.isAdmin);     // Now it's "true"!

Here’s what’s happening: when you spread or merge the parsed object, the __proto__ property gets set on Object.prototype, so every new object gets the injected properties!

*If you use libraries like lodash or handle merging user data with { ...obj } or Object.assign(), you’re especially at risk.*

5. Real World Risks

- Access Control Bypass: An attacker injects flags like isAdmin or authenticated, affecting access checks.

App Logic Manipulation: Any property checked in your app logic can be set by hackers site-wide.

- Possible Code Execution: In rare cases, prototype changes can lead to code injection, DoS, or more.

6. How to Fix

Upgrade Immediately:
Version 4.1.2 and above of fast-xml-parser blocks the parsing of dangerous keys like __proto__.

npm install fast-xml-parser@^4.1.2

Never trust user-supplied data:
Always validate and sanitize data, especially when using unsafe serialization.

Reference:
- fast-xml-parser changelog 4.1.2
- NVD entry for CVE-2023-26920
- Security advisory on GitHub

Stay Safe!

Node.js and JavaScript ecosystems are powerful, but these prototype quirks can bite hard. Take this CVE as a reminder to keep your libraries up to date, watch what you parse, and never trust anything from the outside without a good scrub!

Timeline

Published on: 12/12/2023 17:15:07 UTC
Last modified on: 12/14/2023 20:41:19 UTC