Skip to content

child_process: use module.exports.spawn in fork and execFile#62666

Open
robertsLando wants to merge 1 commit intonodejs:mainfrom
robertsLando:child-process-fix-spawn-exports
Open

child_process: use module.exports.spawn in fork and execFile#62666
robertsLando wants to merge 1 commit intonodejs:mainfrom
robertsLando:child-process-fix-spawn-exports

Conversation

@robertsLando
Copy link
Copy Markdown

@robertsLando robertsLando commented Apr 10, 2026

fork() and execFile() call the locally-scoped spawn() function
directly, bypassing any wrapping applied to child_process.spawn via
module exports.

This is inconsistent with exec(), which correctly uses
module.exports.execFile() (see lib/child_process.js:236).

The problem

APM tools (New Relic, Datadog), security monitors, and testing
frameworks commonly wrap child_process.spawn on exports to intercept
child process creation. With the current code, processes spawned
through fork() and execFile() silently bypass these wrappers, while
exec() correctly goes through them.

const cp = require('child_process');
const originalSpawn = cp.spawn;

cp.spawn = function (...args) {
  console.log('spawn intercepted');
  return originalSpawn.apply(this, args);
};

cp.exec('echo hi');       // intercepted (exec β†’ module.exports.execFile β†’ ... β†’ spawn)
cp.fork('./worker.js');   // NOT intercepted (fork β†’ local spawn)
cp.execFile('ls', []);    // NOT intercepted (execFile β†’ local spawn)

The fix

Change fork() and execFile() to call module.exports.spawn()
instead of the locally-scoped spawn(), consistent with the pattern
already used by exec().

Refs: yao-pkg/pkg#231

`fork()` and `execFile()` call the locally-scoped `spawn()` function
directly, bypassing any wrapping applied to `child_process.spawn` via
module exports. This is inconsistent with `exec()`, which correctly
uses `module.exports.execFile()`.

APM tools, security monitors, and testing frameworks that wrap
`child_process.spawn` to intercept child process creation silently
miss processes spawned through `fork()` and `execFile()`.

Fix both functions to use `module.exports.spawn()`, consistent with
the existing `exec()` pattern.

Signed-off-by: Daniel Lando <daniel.sorridi@gmail.com>
@nodejs-github-bot nodejs-github-bot added child_process Issues and PRs related to the child_process subsystem. needs-ci PRs that need a full CI run. labels Apr 10, 2026
@Renegade334
Copy link
Copy Markdown
Member

For context:

This is inconsistent with exec(), which correctly uses
module.exports.execFile()

This was a leftover from when the child_process methods existed as module.exports properties rather than as module-declared functions (aa00968). AFAIA, the decision to leave this here was a convenience thing to avoid branch conflicts, not a statement of intent for facilitating the monkeypatching of API internals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

child_process Issues and PRs related to the child_process subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants