CVE-2026-55388: Piscina Prototype Pollution to Remote Code Execution in Worker Threads
Piscina is a Node.js library that manages worker threads—a way to run code in parallel without blocking the main application. A vulnerability in how piscina handles configuration allows an attacker to inject malicious code by polluting JavaScript's Object.prototype, a shared object that all objects inherit from. When an attacker taints Object.prototype.filename before piscina tries to load a worker script, piscina will unknowingly use the attacker's malicious file path instead of the intended one, executing arbitrary code with the privileges of the worker thread. The vulnerability affects versions before 6.0.0-rc.2, 5.2.0, and 4.9.3.
Source data · NVD / CISA · public domain
- CVSS
- 3.1 · 8.1 HIGH · CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
- Weaknesses (CWE)
- CWE-1321, CWE-94
- Affected products
- 0 configuration(s)
- Published / Modified
- 2026-06-22 / 2026-06-23
NVD description (verbatim)
piscina is a node.js worker pool implementation. Prior to 6.0.0-rc.2, 5.2.0, and 4.9.3, piscina's constructor and run() paths read the filename option via plain member access. Both reads fall through the prototype chain when the caller's options object doesn't have filename as an own property. When Object.prototype.filename is polluted upstream the inherited value flows to worker_threads.Worker import and the attacker's .mjs runs in the worker. This vulnerability is fixed in 6.0.0-rc.2, 5.2.0, and 4.9.3.
2 reference(s) · View on NVD →
SEC.co analysis · AI-assisted, reviewed against source
Technical summary
The vulnerability stems from piscina's unsafe property access patterns in both the constructor and run() method. When resolving the filename option, the code performs plain member access (e.g., options.filename) without explicitly checking for own properties via hasOwnProperty(). This causes property lookups to traverse the prototype chain. An upstream prototype pollution attack—typically achieved by malicious dependencies or user-controlled input processed with unsafe object merging—can poison Object.prototype.filename. The attacker-controlled filename is then passed directly to worker_threads.Worker(), which interprets it as a module path and executes the attacker's .mjs (ECMAScript module) file in the worker context. The affected code paths include initialization and task execution, broadening the attack surface.
Business impact
Applications using piscina are at risk if they process untrusted input or depend on packages that might be compromised. Successful exploitation allows an attacker to execute arbitrary Node.js code within worker threads, potentially leading to data exfiltration, manipulation of business logic, lateral movement within the application, or denial of service. The impact is particularly severe in multi-tenant or SaaS environments where worker threads process user requests. Organizations should prioritize patching especially if piscina is used in backend services handling sensitive data or critical workflows.
Affected systems
Piscina versions prior to 4.9.3, 5.2.0, and 6.0.0-rc.2 are vulnerable. The vulnerability requires a prototype pollution vector upstream of piscina—either through direct malicious code execution in the same process, a compromised dependency, or an unsafe deserialization/merging operation. Applications are at risk if they: (1) depend on piscina, (2) are exposed to prototype pollution from dependencies or untrusted input processing, and (3) handle sensitive operations in worker threads. Verify your piscina version by running 'npm list piscina' and cross-reference against the fixed versions.
Exploitability
Exploitation requires two conditions: (1) a prototype pollution vulnerability accessible before piscina instantiation or during task execution, and (2) the ability to place a malicious .mjs file in a location predictable or controllable by the attacker. The CVSS score of 8.1 (HIGH) reflects the high impact of code execution but moderate complexity due to the prerequisite of prototype pollution. This is not a standalone remote vulnerability—it amplifies existing prototype pollution flaws in the application or its dependencies. Real-world risk depends on your supply chain hygiene and input validation practices.
Remediation
Upgrade piscina immediately to version 4.9.3, 5.2.0, or 6.0.0-rc.2 or later. These versions fix the vulnerability by ensuring filename resolution uses safe property access (checking own properties only, not inherited ones). After patching, conduct a security review of your dependency tree to identify and mitigate any prototype pollution sources. Consider using npm audit to detect known vulnerabilities in transitive dependencies, and implement strict package management controls (pinned versions, lock files, verified sources).
Patch guidance
Update piscina via your package manager: 'npm update piscina' (if using compatible version ranges) or 'npm install [email protected]' (or @4.9.3 or @6.0.0-rc.2, depending on your major version requirement). Verify the update with 'npm list piscina'. Test thoroughly in a staging environment to ensure worker thread functionality remains intact. If you're on a major version below 4, consult the piscina changelog to plan a broader upgrade strategy, as you may need to migrate.
Detection guidance
Monitor your Node.js application logs for unexpected worker thread initialization or unusual module loading paths. Check for signs of prototype pollution in your dependency chain: audit for packages with known CVEs related to unsafe object merging or deserialization. Use static analysis tools (ESLint plugins, SAST scanners) to flag unsafe prototype access patterns in your codebase. Runtime detection is challenging; focus on preventing prototype pollution upstream by validating and sanitizing all external input before object operations.
Why prioritize this
While this vulnerability requires a prototype pollution precondition, the consequence—arbitrary code execution in worker threads—is severe. Many real-world applications use piscina in production, and prototype pollution is a known attack vector in JavaScript ecosystems. The combination of high impact, reasonable exploitability in supply-chain or dependency-injection scenarios, and broad use justifies immediate patching. Prioritize if piscina is deployed in services handling sensitive data or user requests.
Risk score, explained
The CVSS 8.1 score reflects: High Confidentiality, Integrity, and Availability impact (code execution in worker threads can steal, modify, or crash data). Network attack vector acknowledges that prototype pollution can originate from remote sources (compromised packages, user input). Attack complexity is High because a prototype pollution precondition is required, reducing the standalone exploitability. The score appropriately captures the severity of the consequence while acknowledging the prerequisite condition.
Frequently asked questions
Does this vulnerability require internet access to exploit?
No, but the prototype pollution precondition often originates from external sources: a malicious npm package, a compromised dependency, or unsanitized user input processed by the application. Once prototype pollution occurs in the same Node.js process, piscina can be exploited without additional network access.
Can we mitigate this without upgrading piscina?
Mitigation without upgrading is difficult but possible in limited scenarios. If you control all inputs and dependencies, you can reduce prototype pollution risk by avoiding unsafe object merging patterns (e.g., using Object.assign() on untrusted objects without validation) and validating piscina options explicitly before passing them. However, upgrading is the only complete fix.
What if we use require() instead of .mjs modules in our workers?
The vulnerability specifically mentions .mjs (ECMAScript module) execution. If your workers exclusively use CommonJS, the risk may be reduced—but the core issue (attacker controlling the filename path) persists and could still lead to unexpected code execution. Upgrade regardless.
How do we detect if we've been compromised?
Check your Node.js application logs for unexpected worker module loads, especially from unusual file paths. Review your npm-shrinkwrap.json or package-lock.json for unexpected package versions or sources. Perform a full code review of recent changes, particularly in dependency updates. If you suspect active exploitation, engage incident response to analyze memory dumps and file system changes on affected servers.
This analysis is provided for informational purposes and reflects publicly available vulnerability data as of the publication date. The vulnerability details, CVSS score, and patch information are based on official vendor advisories and CVE records. Organizations must verify patch availability and compatibility within their specific environment. This document does not constitute legal, compliance, or professional security advice. Consult vendor documentation and your own security team before deploying patches or implementing mitigations. SEC.co makes no warranty regarding the accuracy, completeness, or timeliness of this analysis. Source: NVD (public-domain), retrieved 2026-07-28. Analysis generated by SEC.co (claude-haiku-4-5).
Related vulnerabilities
- CVE-2026-44495HIGHAxios Prototype Pollution Gadget Vulnerability (0.31.0 & 1.15.1)
- CVE-2026-12208MEDIUMPrototype Pollution in jsonata-js Library—Exploitation and Remediation Guide
- CVE-2026-12209MEDIUMRubyLouvre Avalon Prototype Pollution Vulnerability – Exploitation Active
- CVE-2026-10904HIGHChrome V8 Sandbox Escape Remote Code Execution
- CVE-2026-10928HIGHScript Injection in Google Chrome Headless – CVSS 8.8 High Severity
- CVE-2026-11231HIGHChrome Safe Browsing Code Execution on macOS – Patch Now
- CVE-2026-11688HIGHChrome SVG Sandbox Escape RCE Vulnerability – Patch Urgently
- CVE-2026-1829HIGHContent Visibility for Divi Builder Plugin RCE (v4.02 and below)