
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-104849 is a prototype pollution gadget to remote code execution (RCE) vulnerability in Tinypool, a minimal Node.js worker thread pool library. When pool.run(task, options) is called with a caller-supplied options object, Tinypool reads the filename property without verifying it is an own property, allowing a polluted Object.prototype.filename to redirect the worker pool to load an attacker-controlled JavaScript module. All versions of Tinypool prior to 2.1.2 (i.e., <= 2.1.0) are affected; calls to pool.run(task) with no second argument are not affected. The vulnerability was published on August 30, 2026, and carries a CVSS v4.0 base score of 9.5 (Critical) (Github Advisory).
The root cause is a combination of CWE-1321 (Prototype Pollution) and CWE-94 (Code Injection): Tinypool reads options.filename via a standard property lookup rather than using Object.hasOwn() or Object.prototype.hasOwnProperty.call(), so a polluted Object.prototype.filename is resolved when the caller-supplied options object lacks its own filename property. An attacker must first achieve prototype pollution through an upstream gadget in the same application (e.g., lodash.merge, qs.parse, or similar functions processing attacker-controlled input), then trigger a pool.run(task, options) call where the options object has no own filename. The fix, implemented in PR #135, wraps all user-supplied option objects with withNullPrototype() — a helper that copies own properties onto a null-prototype object via Object.assign(Object.create(null), source) — before any property is read (Github Advisory, Fix PR, Fix Commit). A complete, runnable proof-of-concept is included in the security advisory (Github Advisory).
Successful exploitation allows an attacker to redirect the Tinypool worker pool to load and execute arbitrary attacker-controlled JavaScript with the full privileges of the host Node.js process. The malicious worker receives all task data passed to pool.run() — which may include sensitive request bodies, credentials, or business logic data — enabling both remote code execution and data exfiltration or modification. The CVSS v4.0 scoring reflects high confidentiality, integrity, and availability impact on both the vulnerable and subsequent systems, making this a total-compromise scenario for affected applications (Github Advisory).
A complete, runnable JavaScript proof-of-concept demonstrating the full attack chain (prototype pollution → malicious worker execution → task data exfiltration) is publicly available in the GitHub security advisory (Github Advisory). The NVD SSVC assessment classifies exploitation status as "poc" and the vulnerability as automatable. The EPSS score is approximately 0.39% (31st percentile), and there is no current evidence of in-the-wild exploitation or CISA KEV catalog inclusion (Github Advisory). Exploitation requires a chained precondition: a reachable prototype pollution gadget elsewhere in the application, limiting the attack surface compared to standalone RCE vulnerabilities.
lodash.merge(obj, JSON.parse(userInput)), qs.parse(queryString), or similar), reachable via a public HTTP endpoint.{"__proto__": {"filename": "/attacker/path/malicious-worker.mjs"}}) to the vulnerable endpoint, causing Object.prototype.filename to be set to the path of an attacker-controlled module.malicious-worker.mjs) is accessible at the polluted path on the server's filesystem. Example content: export default async (task) => ({ by: 'attacker', stolenRequestBody: task }).pool.run(task, options): Send an HTTP request to any application endpoint that calls pool.run(req.body, { signal: ac.signal }) or similar — passing a caller-supplied options object without an own filename property.filename, the prototype chain lookup resolves to Object.prototype.filename, which now points to the malicious module. Tinypool loads and executes it in a worker thread.res.json(result)) sends this back to the attacker, confirming RCE and data exfiltration (Github Advisory).filename in the Tinypool constructor; application error logs referencing unfamiliar .mjs or .js file paths in worker initialization.malicious-worker.mjs) in application directories or world-writable locations accessible to the Node.js process; new files created by the Node.js process user in non-standard directories.{"by": "attacker", "stolenRequestBody": ...} in application API responses.exec, spawn) initiated from within Node.js worker threads that are inconsistent with normal application behavior; unexpected access to sensitive files (e.g., /etc/passwd, environment files, database credentials) by the Node.js process.Upgrade Tinypool to version 2.1.2 or later, which wraps all user-supplied option objects with a null-prototype copy before reading any properties, preventing prototype chain lookups (Release v2.1.2, Fix Commit). As a defense-in-depth measure, audit the application for prototype pollution gadgets (e.g., unsafe use of lodash.merge, qs.parse, JSON.parse into merge operations) and sanitize or freeze Object.prototype at application startup. Applications that call pool.run(task) without a second argument are not affected and do not require immediate action beyond upgrading (Github Advisory).
The vulnerability was noted as the Tinypool counterpart to a previously discovered piscina vulnerability (GHSA-x9g3-xrwr-cwfg), indicating a pattern of prototype pollution exposure in Node.js worker pool libraries forked from piscina (Github Advisory). Multiple downstream projects — including Blockcast/paperclip, ethereum-optimism/actions, percona/pmm-extensions, and Expensify/App — opened dependency update PRs shortly after disclosure, reflecting broad adoption of Tinypool in the Node.js ecosystem (Fix PR). SystemTek published a brief coverage article highlighting the critical severity rating (SystemTek).
Fix availability across major Linux distributions and their releases.
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."