JavaScript

JavaScript

By DeepSource

Unsafe argument to child_process JS-D023

Security

child_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

  • Executing /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

  1. Avoid using child_process.exec, and never use it if the command contains any input that changes based on user input.

  2. 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.

  3. 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.

Bad Practice

app.get("/resource", (req, res) => {
  const foo = req.params.foo
  child_process.exec("ls " + foo, (err, data) => {
    console.log(data)
  })
})

Recommended

app.get("/resource", (req, res) => {
  const foo = req.params.foo
  const safeFoo = sanitize(foo)
  child_process.exec("ls " + safeFoo, (err, data) => {
    console.log(data)
  })
})

References