← Blog · · df00tech

Prototype Pollution in tinypool Leads to RCE in Vitest-Based Build and Test Pipelines

breaking ghsa npm CVE-2026-104848

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 tinypool and vitest are 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 --require flag usage tied to test/build steps, and for Node processes spawning workers with unexpected execArgv or NODE_OPTIONS environment 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.

Get new detections in your inbox

New ATT&CK coverage plus CISA KEV / CVE detection rules, roughly weekly. No spam, unsubscribe anytime.