The vulnerability lies in the static code generation feature of pbjs, the command-line interface for protobuf.js. When pbjs generates static JavaScript files from a protobuf schema, it uses names from the schema (like message names, field names, etc.) to create identifiers (variable and function names) in the output JavaScript code. The vulnerability exists because these names were not properly sanitized before being written into the generated code. An attacker could craft a schema with malicious names containing arbitrary JavaScript code. When pbjs processes this schema, the malicious code is injected into the output file. If this generated file is later executed or imported by an application, the injected code runs, leading to a code injection vulnerability.
The analysis of the security patches shows two key functions that were fixed to address this issue:
-
escapeName in cli/targets/static.js: This function is directly responsible for making schema names safe to use as identifiers in the generated static code. The original implementation was insufficient as it only checked for reserved JavaScript keywords, but allowed other special characters that could be used to terminate a string and inject new code.
-
codegen in lib/codegen/index.js (and its equivalent in src/util/codegen.js for other versions): This is a more generic utility for creating functions dynamically. It was also found to be vulnerable as it did not sanitize the provided function name. This could be exploited if a schema name was used to define a function name passed to this utility.
The patches for both affected version ranges introduce robust sanitization in these functions, primarily by removing any characters that are not valid in a JavaScript identifier. This ensures that even if a schema contains malicious names, they cannot be used to inject code into the generated output.