The vulnerability is a classic case of prototype pollution in the protobuf.js library. An attacker who can control the protobuf schema or a JSON descriptor can inject properties into Object.prototype. This is a serious vulnerability that can lead to a process-wide denial of service, and potentially other security issues depending on the application's logic.
The root cause is insufficient sanitization of property names when processing untrusted schemas and data. The library failed to block property names like __proto__, constructor, and prototype in several key areas:
-
Schema Parsing: The parse function and the ReflectionObject.setOption method allowed options with malicious names, which were then set using the vulnerable util.setProperty utility. This allowed an attacker to write to arbitrary paths on an object, eventually reaching the global Object.prototype.
-
Data Conversion: The Type.fromObject method did not safely handle input objects with a __proto__ key, allowing for direct prototype pollution of message instances.
-
Binary Deserialization: The Type.decode method did not safely handle map fields with a string key of __proto__, allowing a crafted binary payload to pollute the prototype of a message instance.
The patches address these issues by adding explicit checks to disallow or safely handle these special property names across all identified vulnerable code paths, effectively preventing the prototype pollution.