Search code examples
bashsecuritycode-injectionjavascript-injection

prevent script injection when spawning command line with input arguments from external source


I've got a python script that wraps a bash command line tool, that gets it's variables from external source (environment variables). is there any way to perform some soft of escaping to prevent malicious user from executing bad code in one of those parameters.

for example if the script looks like this

/bin/sh 

/usr/bin/tool ${VAR1} ${VAR2}

and someone set VAR2 as follows

export VAR2=123 && \rm -rf /

so it may not treat VAR2 as pure input, and perform the rm command.

Is there any way to make the variable non-executable and take the string as-is to the command line tool as input ?


Solution

  • The correct and safe way to pass the values of variables VAR1 and VAR2 as arguments to /usr/bin/tool is:

    /usr/bin/tool -- "$VAR1" "$VAR2"
    
    • The quotes prevent any special treatment of separator or pattern matching characters in the strings.
    • The -- should prevent the variable values being treated as options if they begin with - characters. You might have to do something else if tool is badly written and doesn't accept -- to terminate command line options.
    • See Quotes - Greg's Wiki for excellent information about quoting in shell programming.
    • Shellcheck can detect many cases where quotes are missing. It's available as either an online tool or an installable program. Always use it if you want to eliminate many common bugs from your shell code.
    • The curly braces in the line of code in the question are completely redundant, as they usually are. Some people mistakenly think that they act as quotes. To understand their use, see When do we need curly braces around shell variables?.
    • I'm guessing that the /bin/sh in the question was intended to be a #! /bin/sh shebang. Since the question was tagged bash, note that #! /bin/sh should not be used with code that includes Bashisms. /bin/sh may not be Bash, and even if it is Bash it behaves differently when invoked as /bin/sh rather than /bin/bash.
    • Note that even if you forget the quotes the line of code in the question will not cause commands (like rm -rf /) embedded in the variable values to be run at that point. The danger is that badly-written code that uses the variables will create and run commands that include the variable values in unsafe ways. See should I avoid bash -c, sh -c, and other shells' equivalents in my shell scripts? for an explanation of (only) some of the dangers.