Every CVE Search/ Get API key

CVE-2026-102992

piscina: Prototype-pollution gadget in ThreadPool.options allows RCE via execArgv / loadBalancer / env

9.2 CriticalFix available

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.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.51%Unchanged since Oct 1, 2026
90%50%10%1%

What each source reports

CVE List Score used 9.2

piscina: Prototype-pollution gadget in ThreadPool.options allows RCE via execArgv / loadBalancer / env

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.

Record
CVE-2026-102992
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1321
Updated
2026-11-02
EUVDEUVD-2026-90364 9.2

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.

Record
EUVD-2026-90364
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-67c8-pqhq-4rmx 9.2

piscina: Prototype-pollution gadget in ThreadPool.options allows RCE via execArgv / loadBalancer / env

Summary

A prototype-pollution gadget in ThreadPool.options allows an attacker who can pollute Object.prototype to execute arbitrary code in Piscina worker threads, invoke arbitrary functions during task scheduling, or inject environment variables into workers. The root cause is that ThreadPool.options is created as a plain object inheriting from Object.prototype, so any option without an explicit default in kDefaultOptions can be supplied via the prototype chain.

Details

In src/index.ts the ThreadPool constructor builds the resolved options object as a plain object:

this.options = { ...kDefaultOptions, ...options, filename, maxQueue: 0 }

Because this object has Object.prototype as its prototype, reads for properties that are not own properties of the object and are not present in kDefaultOptions fall back to Object.prototype. This means a prototype-pollution primitive (e.g. from a vulnerable merge() or JSON.parse merge elsewhere in the application) can inject values for execArgv, env, loadBalancer, argv, workerData, resourceLimits, niceIncrement, closeTimeout, recordTiming, stricterFIFO, workerHistogram, and trackUnmanagedFds.

The most serious gadget is execArgv, which is passed directly to new Worker(..., { execArgv }). An attacker can set Object.prototype.execArgv = ['--require', '/tmp/attacker.js'], causing every worker to preload and execute the attacker-controlled module on startup.

This issue survived the fix for GHSA-x9g3-xrwr-cwfg / CVE-2026-55388 ("Prototype Pollution Gadget → RCE via inherited options.filename"). That advisory hardened the Piscina constructor's filename read and run()'s filename/name reads, but ThreadPool.options itself was not created with a null prototype. The same class of attack is therefore still possible against any option without an explicit default in kDefaultOptions.

PoC

import { resolve } from 'node:path'
import Piscina from 'piscina'

Object.prototype.execArgv = ['--require', '/tmp/attacker.js']

const pool = new Piscina({
  filename: resolve(import.meta.dirname, 'worker.js'),
  minThreads: 1,
  maxThreads: 1,
})

await pool.run(1)

/tmp/attacker.js is executed in the worker on startup. A full reproduction repository with execArgv, loadBalancer, and env vectors is available at https://github.com/Fcmam5/piscina-pp-poc.

Impact

  • Remote Code Execution: via execArgv (arbitrary --require module preloaded in every worker on spawn).
  • Arbitrary code execution in the main thread: via loadBalancer, an attacker-supplied function that is called during task scheduling.
  • Environment/CLI option injection: via env, which is passed to each worker constructor.
  • Denial of Service / unexpected behavior: via other reachable options such as workerData, resourceLimits, niceIncrement, closeTimeout, recordTiming, etc.

Anyone using Piscina in an application where Object.prototype can be polluted (e.g. through a dependency with a prototype-pollution vulnerability) is impacted.

Record
GHSA-67c8-pqhq-4rmx
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1321
Updated
2026-11-02
NVD 9.2

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.

Record
CVE-2026-102992
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-1321
Updated
2026-11-02
OSV 9.2

piscina: Prototype-pollution gadget in ThreadPool.options allows RCE via execArgv / loadBalancer / env

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.

Record
CVE-2026-102992
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1321
Updated
2026-11-04
OSVGHSA-67c8-pqhq-4rmx 9.2

piscina: Prototype-pollution gadget in ThreadPool.options allows RCE via execArgv / loadBalancer / env

Summary

A prototype-pollution gadget in ThreadPool.options allows an attacker who can pollute Object.prototype to execute arbitrary code in Piscina worker threads, invoke arbitrary functions during task scheduling, or inject environment variables into workers. The root cause is that ThreadPool.options is created as a plain object inheriting from Object.prototype, so any option without an explicit default in kDefaultOptions can be supplied via the prototype chain.

Details

In src/index.ts the ThreadPool constructor builds the resolved options object as a plain object:

this.options = { ...kDefaultOptions, ...options, filename, maxQueue: 0 }

Because this object has Object.prototype as its prototype, reads for properties that are not own properties of the object and are not present in kDefaultOptions fall back to Object.prototype. This means a prototype-pollution primitive (e.g. from a vulnerable merge() or JSON.parse merge elsewhere in the application) can inject values for execArgv, env, loadBalancer, argv, workerData, resourceLimits, niceIncrement, closeTimeout, recordTiming, stricterFIFO, workerHistogram, and trackUnmanagedFds.

The most serious gadget is execArgv, which is passed directly to new Worker(..., { execArgv }). An attacker can set Object.prototype.execArgv = ['--require', '/tmp/attacker.js'], causing every worker to preload and execute the attacker-controlled module on startup.

This issue survived the fix for GHSA-x9g3-xrwr-cwfg / CVE-2026-55388 ("Prototype Pollution Gadget → RCE via inherited options.filename"). That advisory hardened the Piscina constructor's filename read and run()'s filename/name reads, but ThreadPool.options itself was not created with a null prototype. The same class of attack is therefore still possible against any option without an explicit default in kDefaultOptions.

PoC

import { resolve } from 'node:path'
import Piscina from 'piscina'

Object.prototype.execArgv = ['--require', '/tmp/attacker.js']

const pool = new Piscina({
  filename: resolve(import.meta.dirname, 'worker.js'),
  minThreads: 1,
  maxThreads: 1,
})

await pool.run(1)

/tmp/attacker.js is executed in the worker on startup. A full reproduction repository with execArgv, loadBalancer, and env vectors is available at https://github.com/Fcmam5/piscina-pp-poc.

Impact

  • Remote Code Execution: via execArgv (arbitrary --require module preloaded in every worker on spawn).
  • Arbitrary code execution in the main thread: via loadBalancer, an attacker-supplied function that is called during task scheduling.
  • Environment/CLI option injection: via env, which is passed to each worker constructor.
  • Denial of Service / unexpected behavior: via other reachable options such as workerData, resourceLimits, niceIncrement, closeTimeout, recordTiming, etc.

Anyone using Piscina in an application where Object.prototype can be polluted (e.g. through a dependency with a prototype-pollution vulnerability) is impacted.

Record
GHSA-67c8-pqhq-4rmx
CVSS 4.0
9.2 CriticalCVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-1321
Updated
2026-11-02
Show 7 moreShow less
OSVAZL-105657 No score

CVE-2026-102992 affecting package python-tensorboard 2.16.2-6

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.

Record
AZL-105657
Updated
2026-11-02
OSVCLSA-2026-1790888307 No score

TuxCare security update for piscina (1 CVE)

TuxCare rebuilt piscina to address 1 CVE. Fixed in 4.8.0-tuxcare.1.

Record
CLSA-2026-1790888307
Updated
2026-11-02
OSVCLSA-2026-1790937670 No score

TuxCare security update for piscina (1 CVE)

TuxCare rebuilt piscina to address 1 CVE. Fixed in 4.6.1-tuxcare.2.

Record
CLSA-2026-1790937670
Updated
2026-11-02
OSVCLSA-2026-1791028065 No score

TuxCare security update for piscina (1 CVE)

TuxCare rebuilt piscina to address 1 CVE. Fixed in 4.4.0-tuxcare.1.

Record
CLSA-2026-1791028065
Updated
2026-11-02
OSVCLSA-2026-1792472733 No score

TuxCare security update for piscina (1 CVE)

TuxCare rebuilt piscina to address 1 CVE. Fixed in 5.2.0-tuxcare.1.

Record
CLSA-2026-1792472733
Updated
2026-11-02
OSVCLSA-2026-1793206864 No score

TuxCare security update for piscina (2 CVEs)

TuxCare rebuilt piscina to address 2 CVEs. Fixed in 3.2.0-tuxcare.1.

Record
CLSA-2026-1793206864
Updated
2026-11-02
OSVROOT-APP-NPM-CVE-2026-102992 No score

CVE-2026-102992 in piscina - Patched by Root

Root has patched CVE-2026-102992 in the piscina package for Root:npm. Multiple fixed versions available.

Record
ROOT-APP-NPM-CVE-2026-102992
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
piscina
npm
5.0.0 up to 5.3.2
5.3.2
piscina
npm
before 4.9.4
4.9.4
piscina
npm
6.0.0-rc.1 up to 6.0.0-rc.5
6.0.0-rc.5
python-tensorboard
Azure Linux:3
through 2.16.2-6 None known
piscina
TuxCare:npm
4.8.0-tuxcare.0 up to 4.8.0-tuxcare.1, plus listed versions
4.8.0
4.8.0-tuxcare.1
piscina
TuxCare:npm
4.6.1-tuxcare.0 up to 4.6.1-tuxcare.2, plus listed versions
4.6.14.6.1-tuxcare.1
4.6.1-tuxcare.2
piscina
TuxCare:npm
4.4.0-tuxcare.0 up to 4.4.0-tuxcare.1, plus listed versions
4.4.0
4.4.0-tuxcare.1
piscina
TuxCare:npm
5.2.0-tuxcare.0 up to 5.2.0-tuxcare.1, plus listed versions
5.2.0
5.2.0-tuxcare.1
piscina
TuxCare:npm
From an advisory covering 2 CVEs
3.2.0-tuxcare.0 up to 3.2.0-tuxcare.1, plus listed versions
3.2.0
3.2.0-tuxcare.1
piscina
Root:npm
before 4.9.3-aikido.1
4.9.3-aikido.15.3.1-aikido.1
@rootio/piscina
Root:npm
before 4.9.3-root.io.1
4.9.3-root.io.15.3.1-root.io.1

History

History
RecordedChangedSources
affected
factsOSV
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-102992 is a critical vulnerability (CVSS 9.2) in Piscinajs Piscina, published September 30, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.51%, the 43rd percentile. Fixed in piscina 5.3.2.

References

Show 6 moreShow less
MoveEnter Open