/sh-template-tag

NPM package that provides a string template tag for safely composing sh/bash shell commands

Primary LanguageJavaScriptApache License 2.0Apache-2.0

Sisyphus Logo

sh Template Tag

Build Status Dependencies Status npm Coverage Status Install Size Known Vulnerabilities

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.

Usage Example

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)"
#'

*/

API

sh`...`

A tag handler that escapes values so that they contribute the literal characters, returning an ShFragment.

ShFragments are not escaped when they appear outside quotes.

ShFragment(str)

A TypedString subclass that specifies a fragment of a shell command suitable for embedding outside a quoted string and which has balanced delimiters.

ShFragments 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;')

Caveats

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