GeezerVison is showing github.com — child_process: deprecate passing `args` to `spawn` and `execFile` · nodejs/node@c6bca3f
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/deprecations.md +4-1Lines changed: 4 additions & 1 deletion - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -3856,13 +3856,16 @@ deprecated, as their values are guaranteed to be identical to that of `process.f | 3856 | 3856 |
| 3857 | 3857 | <!-- YAML | 3858 | 3858 | changes: | | 3859 | + - version: REPLACEME | | 3860 | + pr-url: https://github.com/nodejs/node/pull/57199 | | 3861 | + description: Runtime deprecation. | 3859 | 3862 | - version: | 3860 | 3863 | - REPLACEME | 3861 | 3864 | pr-url: https://github.com/nodejs/node/pull/57389 | 3862 | 3865 | description: Documentation-only deprecation. | 3863 | 3866 | --> | 3864 | 3867 |
| 3865 | | -Type: Documentation-only | | 3868 | +Type: Runtime | 3866 | 3869 |
| 3867 | 3870 | When an `args` array is passed to [`child_process.execFile`][] or [`child_process.spawn`][] with the option | 3868 | 3871 | `{ shell: true }`, the values are not escaped, only space-separated, which can lead to shell injection. | |
Collapse file Copy file name to clipboardExpand all lines: lib/child_process.js +9Lines changed: 9 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -535,6 +535,7 @@ function copyProcessEnvToEnv(env, name, optionEnv) { | 535 | 535 | } | 536 | 536 | } | 537 | 537 |
| | 538 | +let emittedDEP0190Already = false; | 538 | 539 | function normalizeSpawnArguments(file, args, options) { | 539 | 540 | validateString(file, 'file'); | 540 | 541 | validateArgumentNullCheck(file, 'file'); | @@ -611,6 +612,14 @@ function normalizeSpawnArguments(file, args, options) { | 611 | 612 |
| 612 | 613 | if (options.shell) { | 613 | 614 | validateArgumentNullCheck(options.shell, 'options.shell'); | | 615 | + if (args.length > 0 && !emittedDEP0190Already) { | | 616 | + process.emitWarning( | | 617 | + 'Passing args to a child process with shell option true can lead to security ' + | | 618 | + 'vulnerabilities, as the arguments are not escaped, only concatenated.', | | 619 | + 'DeprecationWarning', | | 620 | + 'DEP0190'); | | 621 | + emittedDEP0190Already = true; | | 622 | + } | 614 | 623 | const command = ArrayPrototypeJoin([file, ...args], ' '); | 615 | 624 | // Set the shell, switches, and commands. | 616 | 625 | if (process.platform === 'win32') { | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-child-process-execfile.js +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -12,6 +12,12 @@ const fixture = fixtures.path('exit.js'); | 12 | 12 | const echoFixture = fixtures.path('echo.js'); | 13 | 13 | const execOpts = { encoding: 'utf8', shell: true, env: { ...process.env, NODE: process.execPath, FIXTURE: fixture } }; | 14 | 14 |
| | 15 | +common.expectWarning( | | 16 | + 'DeprecationWarning', | | 17 | + 'Passing args to a child process with shell option true can lead to security ' + | | 18 | + 'vulnerabilities, as the arguments are not escaped, only concatenated.', | | 19 | + 'DEP0190'); | | 20 | + | 15 | 21 | { | 16 | 22 | execFile( | 17 | 23 | process.execPath, | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-child-process-spawn-shell.js +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -18,6 +18,12 @@ doesNotExist.on('exit', common.mustCall((code, signal) => { | 18 | 18 | })); | 19 | 19 |
| 20 | 20 | // Verify that passing arguments works | | 21 | +common.expectWarning( | | 22 | + 'DeprecationWarning', | | 23 | + 'Passing args to a child process with shell option true can lead to security ' + | | 24 | + 'vulnerabilities, as the arguments are not escaped, only concatenated.', | | 25 | + 'DEP0190'); | | 26 | + | 21 | 27 | const echo = cp.spawn('echo', ['foo'], { | 22 | 28 | encoding: 'utf8', | 23 | 29 | shell: true | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-child-process-spawnsync-shell.js +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 19 | 19 | assert.strictEqual(doesNotExist.status, 127); // Exit code of /bin/sh | 20 | 20 |
| 21 | 21 | // Verify that passing arguments works | | 22 | +common.expectWarning( | | 23 | + 'DeprecationWarning', | | 24 | + 'Passing args to a child process with shell option true can lead to security ' + | | 25 | + 'vulnerabilities, as the arguments are not escaped, only concatenated.', | | 26 | + 'DEP0190'); | | 27 | + | 22 | 28 | internalCp.spawnSync = common.mustCall(function(opts) { | 23 | 29 | assert.strictEqual(opts.args[opts.args.length - 1].replace(/"/g, ''), | 24 | 30 | 'echo foo'); | |
|