sanitize user input for child_process.exec command
Asked Answered
F

2

11

I'm writing a CLI using node and I've arrived at the part where I take user input and append it to a string that is the command for the child_process.exec function.

const CURL_CHILD = exec('npm view --json ' + process.argv[2] + ...

I am trying to figure out what I need to do to process.argv[2] before I pass it to the exec function. I've surfed around for a while and haven't found any questions or answers that address this specific case.

What is the best way to sanitize this user input for this particular use case? What is actually needed here?

Update I'm still surfing around trying to learn and answer my own question and found this link which suggests I use js-string-escape (a node package). I'd really like to use something native/vanilla to do this. Does node have any tools for this?

Update 2

I finally stumbled upon the buzzwords "command injection" and found a slew of articles recommending the use of child_process.execFile or child_process.spawn. I'm still curious if there is a native way to sanitize the input, while still securing the full shell process created by child_process.exec. I am leaving this open in hopes someone can answer it.

Froebel answered 27/3, 2018 at 12:2 Comment(0)
A
3

Your user input arguments may contain variable chars that the shell is going to interpret them in its own way. So for instance, in Linux, $ has a special meaning.

If you want to use such argument as-is avoiding the shell interpretation, you have to escape them. The same we do with some special chars in HTML (eg. < and > has special meaning so we use to escape them in HTML like &lt; and respectively &gt;). The same applies here.

So the answer to your question is first to find out the special chars in your shell/environment and escape them.

A good rule of thumb is to escape chars like double-quote ", single-quote ', space , the dollar-sign $ (because it's an Illuminati symbol, right? ;-), the grave-accent ` and obviously the backslash \.

So let's suppose that your command is the one below. To escape it just use some simple regex like this:

cmd = "npm view --json " + process.argv[2];
escapedCmd = cmd.replace(/(["\s'$`\\])/g,'\\$1');

I hope it helps :-)

Assibilate answered 18/4, 2019 at 10:54 Comment(1)
Don't try to roll your own sanitization -- you're bound to miss a lot of things. Use a sanitization library instead.Overwrite
B
1

Try the npm package escape-it. Should work with *nix OSes, but has some support for Windows, too.

Baugh answered 11/6, 2020 at 7:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.