How do I sanitise user input in a bash script so that I can then pass it as an argument to another shell program? I want to prevent the following:
INPUT="filename;rm -rf /" ls $INPUT
I was thinking it should be enough to surround the user input in double quotes like so:
ls "$INPUT"
but what if there is a double quote in $INPUT
?
Or does bash already deal with this problem?
User input should always be treated as malicious before making it down into lower layers of your application. Always handle sanitizing input as soon as possible and should not for any reason be stored in your database before checking for malicious intent.
Input sanitization is a cybersecurity measure of checking, cleaning, and filtering data inputs from users, APIs, and web services of any unwanted characters and strings to prevent the injection of harmful codes into the system.
Sanitizing and validating inputs is usually the first layer of defense. Sanitizing consists of removing any unsafe character from user inputs, and validating will check if the data is in the expected format and type. Attackers have been using classic flaws for years with a pretty high success rate.
Bash already deals with that. Quoting it is sufficient.
ls "$INPUT"
A rough guide to how the shell parses this line is:
"ls \"$INPUT\"" # Raw command line. ["ls", "\"$INPUT\""] # Break into words. ["ls", "\"filename; rm -rf /\""] # Perform variable expansion. ["ls", "\"filename; rm -rf /\""] # Perform word splitting (no change). ["ls", "filename; rm -rf /"] # Remove quotes.
Because of the quotes the $INPUT
variable does not undergo word splitting. The ls
will look for a file named filename; rm -rf /
.
If you didn't quote it then the expansion would proceed differently:
"ls $INPUT" # Raw command line. ["ls", "$INPUT"] # Break into words. ["ls", "filename; rm -rf /"] # Perform variable expansion. ["ls", "filename;", "rm", "-rf", "/"] # Perform word splitting.
You can at least have consolation that this won't actually execute rm -rf /
. Rather, it'll pass each of those strings as a file name to ls
. You'll ls
some files you didn't intend but at least it won't accidentally execute unwanted commands.
jkugelman$ VAR='.; echo hi' jkugelman$ ls $VAR ls: .;: No such file or directory ls: echo: No such file or directory ls: hi: No such file or directory
Excerpts from "man bash":
QUOTING
Quoting is used to remove the special meaning of certain characters or words to the shell. Quoting can be used to disable special treatment for special characters, to prevent reserved words from being recognized as such, and to prevent parameter expansion.
EXPANSION
Expansion is performed on the command line after it has been split into words. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.
Only brace expansion, word splitting, and pathname expansion can change the number of words of the expansion; other expansions expand a single word to a single word. The only exceptions to this are the expansions of
"$@"
and"${name[@]}"
as explained above (see PARAMETERS).Word Splitting
The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting.
Quote Removal
After the preceding expansions, all unquoted occurrences of the characters
\
,'
, and"
that did not result from one of the above expansions are removed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With