Jun 3, 2026·7 min read·50 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 critical algorithmic complexity Denial of Service (DoS) vulnerability exists in the npm package decode-uri-component versions 0.1.0 through 0.4.1. The package employs an inefficient, high-complexity recursive mechanism when processing invalid percent-encoded sequences, such as isolated continuation bytes. An attacker can exploit this behavior by sending malformed strings, causing the Node.js event loop to block entirely and exhausting CPU resources. This vulnerability is resolved in version 0.5.0 by replacing the recursive parser with a single-pass, linear scanning algorithm.
A critical path traversal vulnerability was discovered in the Kirby CMS media component. Prior to versions 4.9.5 and 5.5.2, Kirby failed to validate path-traversal indicators in requested filenames, allowing attackers to check for the existence of local JSON files, delete them, or bypass directory prefix containment logic under certain web server configurations.
A missing authorization vulnerability (CWE-862) in Kirby CMS (versions 5.0.0 through 5.5.1) allows low-privileged authenticated users with Panel access to write temporary chunk files to disk, leading to potential Denial of Service via storage exhaustion.
An input validation vulnerability in the WebTransport upgrade handler of the Engine.IO server (the core engine driving Socket.IO) allows remote, unauthenticated attackers to trigger a denial of service via application crashes. By sending a crafted session identifier corresponding to a JavaScript prototype property (such as __proto__), an attacker forces the server to reference Object.prototype instead of a valid socket instance, causing a fatal TypeError in the asynchronous execution context.
An authentication bypass vulnerability in @hono/oauth-providers prior to version 0.8.6 allows unauthenticated remote attackers to perform login Cross-Site Request Forgery (CSRF) and forced account linking. Due to a logical 'fail-open' comparison flaw, the middleware validates OAuth callbacks when the state parameter is omitted from both the client cookie and the request query parameters, completely bypassing standard anti-CSRF protections.
CVE-2026-15305 describes a critical security vulnerability within the TYPO3 CMS Form Framework (ext:form) extension. Due to a lifecycle timing mismatch, server-side MIME type validation was bypassed when processing files uploaded via FileUpload or ImageUpload form elements. This allowed remote, unauthenticated attackers to upload arbitrary file types (with the exception of blocked PHP extensions) to the web server's public storage directory.