Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent code/option injection in a bash script

I have written a small bash script called "isinFile.sh" for checking if the first term given to the script can be found in the file "file.txt":

#!/bin/bash

FILE="file.txt"

if [ `grep -w "$1" $FILE` ]; then 
 echo "true"
else
 echo "false"
fi

However, running the script like

> ./isinFile.sh -x

breaks the script, since -x is interpreted by grep as an option. So I improved my script

#!/bin/bash

FILE="file.txt"

if [ `grep -w -- "$1" $FILE` ]; then 
 echo "true"
else
 echo "false"
fi

using -- as an argument to grep. Now running

> ./isinFile.sh -x
false

works. But is using -- the correct and only way to prevent code/option injection in bash scripts? I have not seen it in the wild, only found it mentioned in ABASH: Finding Bugs in Bash Scripts.

like image 345
asmaier Avatar asked Dec 04 '25 19:12

asmaier


2 Answers

There's actually another code injection (or whatever you want to call it) bug in this script: it simply hands the output of grep to the [ (aka test) command, and assumes that'll return true if it's not empty. But if the output is more than one "word" long, [ will treat it as an expression and try to evaluate it. For example, suppose the file contains the line 0 -eq 2 and you search for "0" -- [ will decide that 0 is not equal to 2, and the script will print false despite the fact that it found a match.

The best way to fix this is to use Ignacio Vazquez-Abrams' suggestion (as clarified by Dennis Williamson) -- this completely avoids the parsing problem, and is also faster (since -q makes grep stop searching at the first match). If that option weren't available, another method would be to protect the output with double-quotes: if [ "$(grep -w -- "$1" "$FILE")" ]; then (note that I also used $() instead of backquotes 'cause I find them much easier to read, and quotes around $FILE just in case it contains anything funny, like whitespace).

like image 170
Gordon Davisson Avatar answered Dec 06 '25 09:12

Gordon Davisson


grep -w -- ...

prevents that interpretation in what follows --

EDIT

(I did not read the last part sorry). Yes, it is the only way. The other way is to avoid it as first part of the search; e.g. ".{0}-x" works too but it is odd., so e.g.

grep -w ".{0}$1" ...

should work too.

like image 44
ShinTakezou Avatar answered Dec 06 '25 10:12

ShinTakezou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!