Skip to content

fix: harden constructor against prototype pollution - #252

Open
mcollina wants to merge 1 commit into
mainfrom
fix/prototype-pollution-hardening
Open

mcollina wants to merge 1 commit into
mainfrom
fix/prototype-pollution-hardening

Conversation

@mcollina

@mcollina mcollina commented Oct 6, 2026

Copy link
Copy Markdown
Member

What

Copy caller options onto a null-prototype object in the ThreadStream constructor:

opts = Object.assign(Object.create(null), opts)

This ensures inherited properties (e.g. a polluted Object.prototype.workerOpts, workerData, bufferSize or sync) are never read and flowed into the worker_threads.Worker, where env and execArgv are honored.

Why

Defense-in-depth hardening against prototype pollution. An attacker who can pollute Object.prototype earlier in the same process (a common CWE-1321 primitive) could otherwise get a crafted workerOpts (e.g. { env: { NODE_OPTIONS: --require <file> } }) reaching a spawned worker. Copying options onto a null-prototype object means only the caller's own enumerable properties are used.

The one-line change also covers every other option read (bufferSize, sync, filename, workerData), not just workerOpts.

Tests

Adds test/prototype-pollution.test.js (with a test/report-pollution.js fixture) that pollutes Object.prototype and asserts nothing leaks into the worker:

  • polluted workerOpts.name → worker keeps the default name
  • polluted workerOpts.env → worker environment is not replaced
  • polluted workerData → worker opts are unaffected
  • polluted bufferSize → constructor no longer throws

Verified the regression tests fail against the pre-fix code and pass after the change.

npm test: 74 tests, 71 pass, 3 skipped (yarn-specific), 0 fail.

Copy caller options onto a null-prototype object in the constructor so that
inherited properties (e.g. a polluted Object.prototype.workerOpts, workerData,
bufferSize or sync) are not read and flowed into the Worker, where env and
execArgv are honored.

Add regression tests that pollute Object.prototype and assert nothing leaks
into the worker.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant