child_process
JS-D023child_process.exec
has a simple API which means it is often the first tool developers reach for when they need to run a subprocess.
It is simple to use; pass in a command string, and it will return an error or the command results.
What happens when the arguments you pass to the command depend on user input?
The obvious solution is to take the user input and build your command out using string concatenation. This can lead to remote code execution bugs in your code.
Limitations of using spawn or execFile
/bin/find
with spawn
or execFile
and passing user input directly with a shell command is a security risk, as find
has options which allow for both arbitrary command execution as well as modification and even creation or deletion of files or directories.Best Practices with child_process
Avoid using child_process.exec
, and never use it if the command contains any input that changes based on user input.
Try to avoid letting users pass in options to commands if possible. Typically values are okay when using spawn or execfile, but selecting options via a user-controlled string is a bad idea.
If you must allow for user-controlled options, look at the options for the command extensively, determine which options are safe, and whitelist only those options.
app.get("/resource", (req, res) => {
const foo = req.params.foo
child_process.exec("ls " + foo, (err, data) => {
console.log(data)
})
})
app.get("/resource", (req, res) => {
const foo = req.params.foo
const safeFoo = sanitize(foo)
child_process.exec("ls " + safeFoo, (err, data) => {
console.log(data)
})
})