Skip to main content

Piscina CVE-2026-102992

| EUVDEUVD-2026-90364 CRITICAL
Improperly Controlled Modification of Object Prototype Attributes (Prototype Pollution) (CWE-1321)
2026-09-30 GitHub_M GHSA-67c8-pqhq-4rmx
9.2
CVSS 4.0 · Vendor: GitHub_M
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify app using vulnerable Piscina
  2. Delivery
    Trigger existing prototype-pollution primitive
  3. Exploit
    Set inherited execArgv/loadBalancer/env on Object.prototype
  4. Execution
    Piscina reads polluted option lacking own default
  5. Persist
    Worker preloads attacker code
  6. Impact
    Code 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.

Act Now Prioritize within 24-48h. Why: CRITICAL severity.
Patch available 0.6% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – 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

piscina 6.0.0-rc.1, < 6.0.0-rc.5
piscina < 4.9.4
piscina 5.0.0, < 5.3.2

Affected Packages

npm piscina fix: 4.9.4, 5.3.2, 6.0.0-rc.5
euvd piscina_6_0_0_rc_1 fix: 6.0.0-rc.5

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

Vendor (GitHub_M) PRIMARY 9.2 CRITICAL
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
vuln.today AI 8.1 HIGH

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.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
4.0 AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Red Hat 8.1 HIGH

Primary rating from Vendor (GitHub_M).

CVSS VectorVendor: GitHub_M

Attack Vector
Network
Attack Complexity
High
Attack Requirements
Present
Privileges Required
None
User Interaction
None
Vulnerable system: Confidentiality
High
Vulnerable system: Integrity
High
Vulnerable system: Availability
High
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

Lifecycle Timeline

2
Patch available
Sep 30, 2026 - 21:04 EUVD
CVE Published
Sep 30, 2026 - 19:50 cve.org
CRITICAL 9.2

DescriptionCVE.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
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 11 npm packages depend on piscina (5 direct, 6 indirect)

Ecosystem-wide dependent count for version 5.0.0.

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

Why It Matters

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.

Business Impact: Severe
Compensating Controls

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

EPSS Score
0.6%
Top 56% exploitable
Prevalence
Medium
popular Node.js worker-pool library, common but not on every server
Threat Intel
1
1 sources
Data Quality
6 sources
Confidence: High
EUVD NVD CVE.org EPSS Vulnrichment GHSA MSRC Vendor GitHub

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.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC No
EPSS 0.6%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact
Very High
Technical Impact
Total

Priority Score

47
Low Medium High Critical
KEV: 0
EPSS: +1
CVSS: +46
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy