Prototype Pollution in tinypool Leads to RCE in Vitest-Based Build and Test Pipelines
GHSA-5gmw-xhrv-c9v3 / CVE-2026-104848 — a critical advisory was published on 2026-10-05 for tinypool, the worker-pool library that underlies Vitest (~42M downloads/week).
What was reported
According to the advisory, tinypool builds its worker options via a plain object spread (this.options = { ...kDefaultOptions, ...options, filename, maxQueue: 0 }) and then reads specific keys off that object before passing them explicitly to Node's worker_threads.Worker. Because the object inherits from Object.prototype, any property an attacker has polluted onto Object.prototype — even though the application never set it — gets resolved through the prototype chain and re-materialized as an explicit, own-property option passed to Worker.
The advisory identifies two keys that reach code execution when polluted on Object.prototype:
execArgv— e.g.['--require', '/path/to/attacker.js'], causing every pool worker to load attacker-controlled code.env— e.g.{ NODE_OPTIONS: '--require /path/to/attacker.js' }, achieving the same effect via environment injection.
A public proof-of-concept is included in the advisory and is reported confirmed on Node 20 for both vectors. The exploit status is listed as PoC-public. No CVSS score was provided in the item.
Why it matters for defenders
This is not a standalone RCE — it's a gadget. Prototype pollution has to originate somewhere else in the dependency tree (the advisory names common historical sources like lodash, qs, minimist, set-value, and deepmerge as examples of the kind of upstream primitive this could chain from). tinypool's handling of worker options then converts that pollution primitive into actual code execution, defeating a protection Node core otherwise provides (Node ignores Worker options inherited from the prototype; tinypool's explicit re-read bypasses that).
Because tinypool sits behind Vitest, the realistic blast radius is developer workstations and CI/test runners rather than production services. Code execution in a CI runner is a supply-chain foothold — potential access to CI secrets, signing keys, and artifact publishing credentials.
What defenders should do now
- Inventory where
tinypoolandvitestare pulled into build/test pipelines, including transitively, and track for a patched release. - Audit the dependency tree for known prototype-pollution sources (older lodash/qs/minimist/deepmerge/set-value versions) that could supply the pollution primitive this gadget needs.
- On CI runners, watch for anomalous child-process or
--requireflag usage tied to test/build steps, and for Node processes spawning workers with unexpectedexecArgvorNODE_OPTIONSenvironment values. - Treat any confirmed prototype-pollution finding in a project that also uses tinypool/Vitest as higher severity than usual, given this chaining path to RCE.
Developing intel
This item was published within the last day and should be treated as developing — expect a patched tinypool release and updated guidance. For full technical details, the proof-of-concept, and the suggested fix, see the original GitHub Security Advisory: GHSA-5gmw-xhrv-c9v3.