Provides a string template tag that makes it easy to compose sh
and
bash
command strings by escaping dynamic values based on the context
in which they appear.
const { sh, ShFragment } = require('sh-template-tag')
function echoCommand (a, b, c) {
return sh`echo -- ${a} "${b}" 'c: ${c}'`
}
console.log(
'%s',
echoCommand(
'; rm -rf / #',
'$(cat /etc/shadow)',
'\'"$(cat /etc/shadow)"\n#'))
/*
Logs the below which does not spawn any subshells:
echo -- '; rm -rf / #' "\$(cat /etc/shadow)" 'c: '"'"'"$(cat /etc/shadow)"
#'
*/
A tag handler that escapes values so that they contribute the literal
characters, returning an ShFragment
.
ShFragment
s are not escaped when they appear outside quotes.
A TypedString
subclass that specifies a fragment of a shell
command suitable for embedding outside a quoted string and which
has balanced delimiters.
ShFragment
s are mintable so to create one, do
const { Mintable } = require('node-sec-patterns')
const { ShFragment } = require('sh-template-tag')
const makeShFragment = Mintable.minterFor(ShFragment, (x) => String(x))
const myShFragment = makeShFragment('echo Hello;')
"Library support for Safe Coding Practices"
Solving shell injection is a much harder problem than query injection since shell scripts tend to call other shell scripts, so properly escaping arguments to one script doesn't help if the script sloppily composes a sub-shell.