Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I escape a string for a shell command in node?

In nodejs, the only way to execute external commands is via sys.exec(cmd). I'd like to call an external command and give it data via stdin. In nodejs there does yet not appear to be a way to open a command and then push data to it (only to exec and receive its standard+error outputs), so it appears the only way I've got to do this right now is via a single string command such as:

var dangerStr = "bad stuff here";
sys.exec("echo '" + dangerStr + "' | somecommand");

Most answers to questions like this have focused on either regex which doesn't work for me in nodejs (which uses Google's V8 Javascript engine) or native features from other languages like Python.

I'd like to escape dangerStr so that it's safe to compose an exec string like the one above. If it helps, dangerStr will contain JSON data.

like image 583
Maciek Avatar asked Nov 22 '09 20:11

Maciek


People also ask

How do you escape a string in a shell?

Escape characters. Escape characters are used to remove the special meaning from a single character. A non-quoted backslash, \, is used as an escape character in Bash. It preserves the literal value of the next character that follows, with the exception of newline.

How do you escape a string in node JS?

escape( ) function is used to produce a percent-encoded query string from a normal string. This method is very similar to the browser's encodeURIComponent functions. This method performs percent-encoding on the given string it means it encodes any string into a URL query string by using the % symbol.

How do you escape special characters in node?

“js escape special characters” Code Answer's Escape characters (Backslash) is used when working with special characters like single quotes, double quotes, apostrophes, and ampersands. Place backslash before the characters to make it display.


2 Answers

This is what I use:

var escapeShell = function(cmd) {
  return '"'+cmd.replace(/(["'$`\\])/g,'\\$1')+'"';
};
like image 89
Sylvain Zimmer Avatar answered Oct 17 '22 11:10

Sylvain Zimmer


You should never rely on escaping unknown input going to a shell parameter - there will almost always be some edge-case that you haven't thought of that allows the user to execute arbitrary code on your server.

Node has support for calling a command and passing each argument separately, with no escaping required. This is the safest way to do it:

const { spawn } = require('child_process');
// Note that the arguments are in an array, not using string interpolation
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

The documentation is here

like image 29
Will Richardson Avatar answered Oct 17 '22 11:10

Will Richardson