Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessIdentify app using vulnerable Piscina
-
DeliveryTrigger existing prototype-pollution primitive
-
ExploitSet inherited execArgv/loadBalancer/env on Object.prototype
-
ExecutionPiscina reads polluted option lacking own default
-
PersistWorker preloads attacker code
-
ImpactCode execution in worker thread
Vulnerability Assessment
| Weakness |
CWE
ASVS 5.0
V3 - Web Frontend Security Prototype pollution prevention
MITRE ATT&CK
2 techniques across 2 tactics: Execution, Initial Access The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires that the host application (1) uses a vulnerable Piscina version (before 4.9.4, 5.3.2, or 6.0.0-rc.5) AND (2) already contains a separate prototype-pollution primitive allowing the attacker to set inherited properties on Object.prototype. The abused options are those WITHOUT an own default on ThreadPool.options - specifically execArgv (preloads attacker code into workers via the Node Worker constructor), loadBalancer (an inherited function executed during task scheduling), and env (alters worker environment). The critical LIMITING factor is that Piscina in isolation is not vulnerable: absent a pre-existing prototype-pollution bug in the application, none of these inherited values can be injected. There is no user interaction required and no authentication to Piscina itself, but the AT:P/AC:H reflect the mandatory secondary primitive. |
| Impact | This is a prototype-pollution 'gadget' rather than a standalone remotely-exploitable flaw. The vendor CVSS 4.0 score of 9.2 (Critical) reflects the worst-case technical impact - code execution in worker threads via an inherited execArgv preload (VC:H/VI:H/VA:H) - but the same vector honestly encodes the key limiter: AC:H and AT:P (Attack Requirements: Present). Both signal that exploitation is NOT self-contained: the description explicitly states it requires 'a separate prototype-pollution primitive' already present in the consuming application. Without that pre-existing primitive, Piscina alone is not exploitable, so the effective real-world risk is materially lower than the 9.2 headline for most deployments. No EPSS score, no CISA KEV listing, and no public POC were provided in the input, so there is no evidence of active exploitation - treat this as 'no public exploit identified at time of analysis.' The PR:N in the vector reflects that no authentication to Piscina itself is needed, but this should not be read as 'trivially remotely exploitable' given the AT:P dependency. The 'Information Disclosure' tag understates the true impact: the primary consequence per the description is arbitrary code preloading (code execution) in worker threads via execArgv and loadBalancer, plus environment tampering via env. Net: a genuine, well-scoped supply-chain hardening fix for apps that also carry a prototype-pollution bug, but not a drop-everything remote 0-day for the average deployment. |
| Exploit ScenarioDerived | An application uses Piscina for its worker pool and also contains a separate prototype-pollution vulnerability (e.g. an unsafe recursive merge of attacker JSON). The attacker pollutes Object.prototype.execArgv (or loadBalancer/env); when Piscina constructs its ThreadPool options as a plain object without an own default for that key, the polluted inherited value flows into the Node.js Worker constructor and preloads attacker-controlled code in a worker thread, yielding code execution. No public exploit was identified at time of analysis. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Sep 30, 2026
Prototype-pollution gadget in the Piscina Node.js worker-pool library allows an attacker who already controls a separate prototype-pollution primitive in the host application to escalate that primitive into worker-thread code preload and execution: an inherited execArgv value is passed straight to the Node.js Worker constructor, an inherited loadBalancer function runs during task scheduling, and inherited env values reshape worker environments. The flaw affects Piscina releases before 4.9.4 (4.x), before 5.3.2 (5.x), and before 6.0.0-rc.5 (6.x RC); exploitation is unauthenticated from Piscina's perspective and needs no user interaction, but the assessed vector (AV:N/AC:H, CVSS 4.0 AT:P) confirms it is not standalone-exploitable without a pre-existing prototype-pollution bug in the consuming application. No public exploit code was identified at time of analysis and the issue is not confirmed actively exploited (no CISA KEV listing).
RemediationAI
Vendor-released patch: upgrade to Piscina 4.9.4 (4.x), 5.3.2 (5.x), or 6.0.0-rc.5 (6.x pre-release) per GHSA-67c8-pqhq-4rmx; the fix wraps option objects in Object.create(null) via the new withNullPrototype() helper (commits 0cb12fca37f526065b072592afe954574dcc656f, 2f69f67159a0e48b38fd61fa4a91c2fdc19fff72, 5be7bbb19e3787bb698862cd516121a578d690f7, bebbda255c2981cecddd36b171b94be2fd41c9a6). Because Piscina alone is not exploitable, the highest-value compensating control is eliminating the upstream prototype-pollution primitive in your own code: reject or strip __proto__, prototype, and constructor keys from any user-controlled input that is merged into objects, prefer Map or Object.create(null) for keyed data, and deep-freeze Object.prototype (Object.freeze(Object.prototype)) - noting that freezing can break libraries that legitimately mutate built-in prototypes. As a runtime hardening measure on Node.js, launch with --disable-proto=throw (or =delete) to neutralize the __proto__ accessor, accepting that code relying on __proto__ will fail. If you cannot upgrade immediately, validate and whitelist the option object you pass to new Piscina(...), explicitly setting execArgv, env, and loadBalancer with own properties, and avoid passing attacker-influenced data anywhere near pool options; audit for any dynamic property assignment that could set inherited values on Object.prototype, since that is the mandatory precondition for this gadget chain.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in npm, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Piscina is a worker-thread pool for Node.js. In src/index.ts the ThreadPool constructor built its options with an object spread - this.options = { ...kDefaultOptions, ...options, filename, maxQueue: 0 } - producing an object that still inherits from Object.prototype. Options that have no own default (notably execArgv, loadBalancer, and env) were therefore resolved through the prototype chain, making them classic prototype-pollution sinks (CWE-1321, Improperly Controlled Modification of Object Prototype Attributes). Because Node's Worker constructor honors execArgv, an inherited value there can preload arbitrary modules into every worker thread; an inherited loadBalancer is invoked as a function during task scheduling; inherited env entries modify the environment of spawned workers. The fix introduces a helper, withNullPrototype(), that copies own properties onto Object.create(null) (for example Object.assign(Object.create(null), source, overrides)) and applies it to the options objects in the ThreadPool constructor and the Piscina class constructor/methods, so option lookups can no longer traverse a polluted prototype chain. The CPE cpe:2.3:a:piscinajs:piscina:*:*:*:*:*:*:*:* reflects that all unpatched npm releases of the piscinajs/piscina package are in scope. Critically, Piscina is the gadget, not the entry point: an attacker must first be able to set inherited properties on Object.prototype via a separate vulnerability in the host application, which is why the assessed vector is AC:H rather than a trivially reachable RCE.
Know when Piscina gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
AC:H because exploitation depends on a pre-existing separate prototype-pollution primitive; PR:N/UI:N as no Piscina auth or interaction is needed; C/I/A:H reflect worker-thread code execution.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
2DescriptionCVE.org
piscina is a node.js worker pool implementation. Prior to 4.9.4, 5.3.2, and 6.0.0-rc.5, Piscina stores ThreadPool.options in src/index.ts as a plain object that inherits from Object.prototype. Applications with a separate prototype-pollution primitive can therefore supply inherited values for security-sensitive options that do not have own defaults. An inherited execArgv value is passed to the Node.js Worker constructor and can preload attacker-controlled code in worker threads, an inherited loadBalancer function can execute during task scheduling, and inherited env values can alter worker environments. This issue is fixed in versions 4.9.4, 5.3.2, and 6.0.0-rc.5.
Blast Radius
ecosystem impact- 11 npm packages depend on piscina (5 direct, 6 indirect)
Ecosystem-wide dependent count for version 5.0.0.
Articles & Coverage 2
Technical POC Analysis
Bug class: CWE-1321, Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution').
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
Piscina, a Node.js worker-pool library used in many server-side applications, contains a critical flaw that can let an attacker escalate a separate prototype-pollution bug into code execution within worker threads. This can lead to unauthorized access, data theft, or service disruption in affected environments, particularly those that process untrusted input. Leadership should treat this as a priority because it amplifies an existing application weakness into a high-impact compromise; no vendor-released patch identified at time of analysis, and no public exploit identified at time of analysis.
No vendor-released patch identified at time of analysis. Interim mitigations include eliminating pre-existing prototype-pollution primitives, hardening object handling (null-prototype objects, Object.freeze(Object.prototype), input validation for __proto__/constructor/prototype), restricting untrusted input to affected services, isolating or disabling Piscina worker threads, and monitoring for anomalous worker-thread execution.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
EUVD-2026-90364
GHSA-67c8-pqhq-4rmx
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB