Introduction
In a private Node.js application's bun.lock file, Trivy detected a critical vulnerability lurking in the dependency tree: CVE-2026-41242 in protobufjs version 7.3.0. This wasn't just a theoretical risk—the vulnerability allowed arbitrary code execution through carefully crafted protobuf definition type fields, potentially giving attackers complete control over the application runtime.
The bun.lock file pinned several protobufjs sub-packages at vulnerable versions, including @protobufjs/codegen@2.0.4, @protobufjs/eventemitter@1.1.0, and @protobufjs/fetch@1.1.0. These components work together to parse and generate code from Protocol Buffer definitions, and a flaw in how type fields were processed created a dangerous injection point.
For developers working with Protocol Buffers in Node.js applications, this vulnerability highlights a critical truth: even widely-used serialization libraries can harbor severe security flaws that require immediate attention.
The Vulnerability Explained
Protocol Buffers (protobuf) is Google's language-neutral data serialization format, and protobufjs is the most popular JavaScript implementation. The library includes a code generation feature (@protobufjs/codegen) that dynamically creates JavaScript functions from protobuf definitions.
CVE-2026-41242 exploits a flaw in how protobufjs handles type field definitions. When processing a .proto file or a JSON-based protobuf definition, the library's codegen component would incorporate type field values directly into generated code without proper sanitization.
Here's what made the vulnerable version dangerous:
// In @protobufjs/codegen@2.0.4, type fields could be injected
// The library would generate code like:
function encode(message) {
// User-controlled type field value inserted here
writer.uint32(/* field tag */).${typeField}(message.value);
}
An attacker could craft a malicious protobuf definition with a type field containing JavaScript code:
{
"nested": {
"MaliciousMessage": {
"fields": {
"payload": {
"type": "string'); require('child_process').exec('malicious-command'); //",
"id": 1
}
}
}
}
}
When protobufjs processed this definition, the injected code would be incorporated into the generated encoder/decoder functions and executed when those functions were called.
Real-World Attack Scenario
Consider this application's context: a Node.js server that might accept protobuf definitions from configuration files, external services, or even user uploads. An attacker who could influence the protobuf schema—even through a seemingly innocuous configuration change—could achieve:
- Remote Code Execution: Running arbitrary system commands on the server
- Data Exfiltration: Accessing environment variables, database credentials, or sensitive files
- Lateral Movement: Using the compromised server to attack other internal systems
The severity is compounded because the code execution happens during the parsing/compilation phase, before any application-level input validation could intervene.
The Fix
The fix involved explicitly pinning protobufjs to version 7.6.5 in the bun.lock file, which pulls in patched versions of all sub-packages:
Before (Vulnerable)
"@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="],
"@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="],
"@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "1.1.2", "@protobufjs/inquire": "1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="],
"@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
After (Patched)
"protobufjs": "7.6.5",
"@protobufjs/codegen": ["@protobufjs/codegen@2.0.5", "", {}, "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g=="],
"@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.1", "", {}, "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg=="],
"@protobufjs/fetch": ["@protobufjs/fetch@1.1.1", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1" } }, "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw=="],
The key changes include:
- Explicit protobufjs pin: Adding
"protobufjs": "7.6.5"to the overrides section ensures the patched version is used throughout the dependency tree - Updated codegen:
@protobufjs/codegenupgraded from 2.0.4 to 2.0.5, which includes sanitization of type field values - Updated sub-packages: All related packages (
eventemitter,fetch) updated to versions that work correctly with the security fixes - Removed vulnerable inquire: The
@protobufjs/inquire@1.1.0dependency was removed from the explicit resolution
The patched version (7.6.5) implements proper escaping and validation of type field definitions, ensuring that malicious strings cannot break out of the intended code context during generation.
Prevention & Best Practices
1. Implement Dependency Scanning in CI/CD
# Example GitHub Actions workflow
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
exit-code: '1'
2. Use Lockfile Auditing
Regularly audit your lockfiles for known vulnerabilities:
# For npm
npm audit
# For bun
bun audit
# For yarn
yarn audit
3. Pin Dependencies Explicitly
When security patches are released, explicitly pin the patched versions in your lockfile overrides to ensure transitive dependencies are also updated.
4. Validate External Protobuf Definitions
If your application loads protobuf definitions from external sources:
// Never load untrusted .proto files directly
// Instead, compile definitions at build time
const root = protobuf.loadSync('trusted-schema.proto');
// If dynamic loading is required, validate the source
function loadProtoDefinition(source, trustedSources) {
if (!trustedSources.includes(source)) {
throw new Error('Untrusted protobuf source');
}
return protobuf.load(source);
}
5. Monitor Security Advisories
Subscribe to security advisories for your critical dependencies:
- GitHub Security Advisories
- npm security advisories
- Snyk vulnerability database
Key Takeaways
- Protobufjs versions before 7.6.5 are vulnerable to CVE-2026-41242—audit your
bun.lock,package-lock.json, oryarn.lockfor affected versions - The
@protobufjs/codegenpackage is the specific attack surface—version 2.0.4 and earlier lack proper type field sanitization - Transitive dependencies can introduce critical vulnerabilities—even if you don't directly import protobufjs, it may exist in your dependency tree
- Lockfile overrides are essential for security patches—adding explicit version pins ensures vulnerable transitive dependencies are replaced
- Code generation libraries require extra scrutiny—any library that generates executable code from external input is a high-risk component
How Orbis AppSec Detected This
- Source: Protobuf definition files or JSON schemas containing type field definitions
- Sink:
@protobufjs/codegen@2.0.4code generation functions that incorporate type fields into generated JavaScript - Missing control: Input sanitization and escaping of type field values before code generation
- CWE: CWE-94 (Improper Control of Generation of Code)
- Fix: Upgraded protobufjs to version 7.6.5 which properly sanitizes type field definitions before incorporating them into generated code
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 code generation libraries can become unexpected attack vectors. The protobufjs vulnerability allowed arbitrary code execution through a seemingly innocuous feature—type field definitions in protobuf schemas. By upgrading to version 7.6.5, the application eliminated this critical risk.
For Node.js developers, this serves as a reminder that dependency security extends beyond your direct imports. Regular vulnerability scanning, explicit version pinning, and automated security tooling are essential practices for maintaining a secure application. The fix in this case was straightforward—a version bump—but detecting the vulnerability required the kind of automated analysis that catches issues before they become incidents.