Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 993bb3b

Browse filesBrowse files
lirantalmarco-ippolito
authored andcommitted
child_process: fix incomplete prototype pollution hardening
Prior pull request (#48726) hardened against prototype pollution vulnerabilities but effectively missed some use-cases which opened a window for prototype pollution for some child_process functions such as spawn(), spawnSync(), and execFileSync(). PR-URL: #53781 Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent 9c5beab commit 993bb3b
Copy full SHA for 993bb3b

2 files changed

+34-1Lines changed: 34 additions & 1 deletion

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎lib/child_process.js‎

Copy file name to clipboardExpand all lines: lib/child_process.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ function normalizeSpawnArguments(file, args, options) {
569569
else
570570
validateObject(options, 'options');
571571

572+
options = { __proto__: null, ...options };
572573
let cwd = options.cwd;
573574

574575
// Validate the cwd, if present.
Collapse file

‎test/parallel/test-child-process-prototype-tampering.mjs‎

Copy file name to clipboardExpand all lines: test/parallel/test-child-process-prototype-tampering.mjs
+33-1Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as common from '../common/index.mjs';
22
import * as fixtures from '../common/fixtures.mjs';
33
import { EOL } from 'node:os';
4-
import { strictEqual } from 'node:assert';
4+
import { strictEqual, notStrictEqual, throws } from 'node:assert';
55
import cp from 'node:child_process';
66

77
// TODO(LiviaMedeiros): test on different platforms
@@ -57,3 +57,35 @@ for (const tamperedUID of [0, 1, 999, 1000, 0n, 'gwak']) {
5757

5858
delete Object.prototype.execPath;
5959
}
60+
61+
for (const shellCommandArgument of ['-L && echo "tampered"']) {
62+
Object.prototype.shell = true;
63+
const cmd = 'pwd';
64+
let cmdExitCode = '';
65+
66+
const program = cp.spawn(cmd, [shellCommandArgument], { cwd: expectedCWD });
67+
program.stderr.on('data', common.mustCall());
68+
program.stdout.on('data', common.mustNotCall());
69+
70+
program.on('exit', common.mustCall((code) => {
71+
notStrictEqual(code, 0);
72+
}));
73+
74+
cp.execFile(cmd, [shellCommandArgument], { cwd: expectedCWD },
75+
common.mustCall((err) => {
76+
notStrictEqual(err.code, 0);
77+
})
78+
);
79+
80+
throws(() => {
81+
cp.execFileSync(cmd, [shellCommandArgument], { cwd: expectedCWD });
82+
}, (e) => {
83+
notStrictEqual(e.status, 0);
84+
return true;
85+
});
86+
87+
cmdExitCode = cp.spawnSync(cmd, [shellCommandArgument], { cwd: expectedCWD }).status;
88+
notStrictEqual(cmdExitCode, 0);
89+
90+
delete Object.prototype.shell;
91+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.