Jun 3, 2026·7 min read·26 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 stored Cross-Site Scripting (XSS) vulnerability exists within plone.restapi, the REST API package for Plone content management system. By supplying a spoofed input MIME type (text/x-html-safe), an attacker can mislead the rendering layer (plone.app.textfield) into assuming that the supplied content is already sanitized. This causes the system to skip the safe_html transform, allowing arbitrary JavaScript to execute in the victim's browser when they view the compromised page.
An untrusted search path vulnerability in the GlobalDatabasePlugin component of the AWS Advanced JDBC Wrapper for Amazon Aurora PostgreSQL allows authenticated, low-privilege database users to hijack administrative session queries. By defining a custom function in a writable schema such as the public schema, an attacker can hijack queries executed automatically during driver-level topology detection. When a highly privileged database user connects to the database utilizing an affected version of the wrapper, the custom function executes under their security context, enabling remote privilege escalation to rds_superuser.
CVE-2026-27771 represents a critical security flaw in Gitea and Forgejo (up to and including version 1.26.1) involving missing authorization checks (CWE-862). Unauthenticated remote attackers can query, enumerate, and download private container images from the OCI-compliant container registry. Additionally, unauthorized users can retrieve private or internal source repository URLs via the Composer package registry metadata API. A public proof-of-concept exists, and threat metrics indicate highly active scanning and exploitation risks.
A missing authorization vulnerability in the Formie plugin for Craft CMS prior to version 3.1.28 allows low-privileged Control Panel users to read and modify sensitive administrative settings, configuration options, and third-party integrations.
CVE-2026-53598 is a directory traversal and arbitrary file read vulnerability in Microsoft Prompty ecosystem loaders across multiple languages. Prior to version 2.0.0-beta.2, the loaders resolved `${file:...}` reference strings inside frontmatter configuration blocks without enforcing that the target file paths resided within authorized directories. This deficiency allows an attacker-controlled configuration file to read sensitive operating system and application files through absolute paths, directory traversal, or symbolic link escapes. The issue is addressed across the Python, C#, Node.js/TypeScript, and Rust ecosystems.
A directory traversal vulnerability exists in the copy subcommand of the proot-distro utility. Due to incomplete path sanitization, local attackers or malicious scripts can read from or write to arbitrary files outside the container rootfs, bypassing isolation barriers and potentially gaining unauthorized access or persistent execution on the host system.