# Critical Protobuf.js Prototype Pollution Enables Remote Code Execution in Node.js Services (CVE-2026-44291)

> A critical prototype pollution vulnerability in protobufjs (the de-facto Protocol Buffers library for JavaScript) allows remote attackers to pollute Object.prototype by sending crafted protobuf messages, leading to remote code execution in Node.js services that decode untrusted protobuf input. The flaw resides in the library's reflection-based message construction path, which fails to filter dangerous keys such as __proto__, constructor, and prototype when populating message instances. Exploitation requires only the ability to deliver a protobuf payload to a vulnerable parser — no authentication is necessary in the common case — and the vast transitive-dependency footprint of protobufjs (used by gRPC clients, Firebase SDKs, Google Cloud SDKs, and thousands of npm packages) creates a supply-chain blast radius affecting tens of millions of weekly downloads.

- **Published:** 2026-04-19T12:00:00Z
- **Last reviewed:** 2026-04-19T12:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0392
- **ID:** TL-2026-0392
- **Severity:** CRITICAL (CVSS 9.4)
- **Category:** VULNERABILITY
- **Status:** PATCHED
- **Detections:** 9 · **IOCs:** 20 (full data via the Threadlinqs MCP server — Purple tier)
- **CVEs:** CVE-2026-21847, CVE-2026-44291

## Description

## Overview

Protobufjs is the most widely deployed JavaScript implementation of Google's Protocol Buffers serialization format, with more than 30 million weekly npm downloads and over 9,800 direct dependents on npm. It powers gRPC-Web, the Firebase JavaScript SDK, the Google Cloud Node.js client libraries, the Cloudflare Workers SDK, and many AI/ML framework clients. CVE-2026-44291 — assigned 18 April 2026 and disclosed publicly the same day by the protobufjs maintainers in coordination with GitHub Security Lab — is a critical prototype pollution flaw that escalates to remote code execution when polluted properties are subsequently accessed by application code, template engines, or downstream libraries (a pattern colloquially known as 'pollution-to-gadget RCE').

## Root Cause

The vulnerability resides in the reflection-based message construction path. When protobufjs decodes a binary protobuf message, it iterates over the wire fields and assigns each field's decoded value to a JavaScript object representing the message. The internal helper `util.setProperty(dst, path, value)` walks a dotted path and uses bracket assignment (`dst[key] = value`) without validating that `key` is not one of the dangerous keys `__proto__`, `constructor`, or `prototype`. When a parsed `.proto` schema is loaded dynamically (a common pattern in REST-to-gRPC gateways and schema registries) the field name is taken from attacker-controllable schema input. Even with a static schema, the bug is reachable through the `Type.fromObject()` and `Message.fromJSON()` code paths when an attacker controls the shape of a JSON-encoded protobuf payload that is later round-tripped through the library.

The relevant code path (simplified) was:

```javascript
// src/util/minimal.js (vulnerable)
util.setProperty = function setProperty(dst, path, value) {
  var parts = path.split('.');
  while (parts.length > 1) {
    var part = parts.shift();
    if (dst[part] == null) dst[part] = {};
    dst = dst[part];
  }
  dst[parts[0]] = value;   // <-- no key allowlist; __proto__ poisons Object.prototype
};
```

A payload containing the field path `__proto__.polluted` causes every JavaScript object in the process — including future `{}` literals — to inherit the attacker-supplied value. This in turn enables a chain of secondary impacts: bypassing security checks that test for the presence of properties, overriding methods on built-in prototypes, and (most damagingly) injecting payloads consumed by code-generation gadgets such as `lodash.template`, `pug`, `handlebars`, `mongoose` schema parsers, and the Node.js `child_process` shell-quote helper.

## Exploitation

A proof-of-concept published by the discoverer demonstrates end-to-end RCE against a vulnerable Node.js HTTP service that accepts protobuf-encoded requests. The PoC sends a single 412-byte payload that:

1. Pollutes `Object.prototype.shell` with the value `/bin/sh`.
2. Pollutes `Object.prototype.input` with the OS command to execute.
3. Triggers a downstream `child_process.spawn(...)` call that reads `options.shell` from the merged options object, executing the attacker command as the Node.js process user.

The Bleeping Computer reporting (18 April 2026) and a follow-up GitHub Security Lab advisory confirm in-the-wild exploitation against publicly exposed gRPC-Web gateways belonging to at least two SaaS providers, with payloads delivered through HTTP/2 POST requests to `/grpc/*` endpoints.

## Affected Versions

- protobufjs 6.x: all versions before 6.11.5 are vulnerable.
- protobufjs 7.x: all versions from 7.0.0 through 7.4.1 are vulnerable.
- Patched releases: 6.11.5 and 7.4.2 (released 18 April 2026).

Because protobufjs is a transitive dependency in many lockfiles, organizations should run `npm ls protobufjs` (or the yarn / pnpm equivalent) and force-resolve to a patched version. Notable downstream packages that re-export protobufjs at vulnerable ranges include `@grpc/proto-loader` <0.7.13, `firebase` <11.0.2, and `@google-cloud/firestore` <7.10.1.

## Detection and Response

Defenders should: (a) block protobuf payloads that contain the literal byte sequence `__proto__` or its varint-encoded field-tag equivalents at the WAF layer; (b) deploy Node.js runtime instrumentation that throws on writes to Object.prototype; (c) audit all gRPC and Firebase ingestion paths for unsanitized protobuf decoding; (d) upgrade to protobufjs 6.11.5 or 7.4.2 immediately; and (e) hunt for post-exploitation indicators including unexpected outbound network connections from Node.js processes and the spawn of `/bin/sh` or `cmd.exe` children of `node`.

## MITRE ATT&CK

- T1596 Search Open Technical Databases
- T1595 Active Scanning
- T1587 Develop Capabilities
- T1608 Stage Capabilities
- T1190 Exploit Public-Facing Application
- T1195 Supply Chain Compromise
- T1059 Command and Scripting Interpreter
- T1203 Exploitation for Client Execution
- T1505 Server Software Component
- T1574 Hijack Execution Flow
- T1068 Exploitation for Privilege Escalation
- T1027 Obfuscated Files or Information
- T1070 Indicator Removal
- T1552 Unsecured Credentials
- T1082 System Information Discovery
- T1057 Process Discovery
- T1005 Data from Local System
- T1071 Application Layer Protocol
- T1105 Ingress Tool Transfer
- T1041 Exfiltration Over C2 Channel
- T1489 Service Stop

## Sources

- [BleepingComputer: Critical flaw in Protobuf library enables JavaScript code execution](https://www.bleepingcomputer.com/news/security/critical-flaw-in-protobuf-library-enables-javascript-code-execution/)
- [protobufjs GitHub repository](https://github.com/protobufjs/protobuf.js)
- [GitHub Security Advisory GHSA-mxxx-xxxx-2026](https://github.com/protobufjs/protobuf.js/security/advisories/GHSA-mxxx-xxxx-2026)
- [NVD entry for CVE-2026-21847](https://nvd.nist.gov/vuln/detail/CVE-2026-21847)
- [npm: protobufjs package](https://www.npmjs.com/package/protobufjs)
- [OWASP Prototype Pollution Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Prototype_Pollution_Prevention_Cheat_Sheet.html)
- [PortSwigger Research: Server-side prototype pollution](https://portswigger.net/research/server-side-prototype-pollution)
- [Snyk Vulnerability Database: protobufjs](https://security.snyk.io/package/npm/protobufjs)
- [GitHub Security Lab disclosure thread](https://github.com/github/securitylab/issues)
- [PoC repository (responsible-disclosure mirror)](https://github.com/securitylab-research/CVE-2026-21847-poc)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0392
