我编写了一个名为“isinFile.sh”的小型bash脚本,用于检查是否可以在文件“file.txt”中找到给脚本的第一个术语:
#!/bin/bash
FILE="file.txt"
if [ `grep -w "$1" $FILE` ]; then
echo "true"
else
echo "false"
fi
但是,运行像
这样的脚本> ./isinFile.sh -x
打破了脚本,因为-x
被grep
解释为一个选项。
所以我改进了我的脚本
#!/bin/bash
FILE="file.txt"
if [ `grep -w -- "$1" $FILE` ]; then
echo "true"
else
echo "false"
fi
使用--
作为grep的参数。现在正在运行
> ./isinFile.sh -x
false
的工作原理。但是使用--
正确且唯一的方法来阻止bash脚本中的代码/选项注入?我没有在野外看到它,只是在ABASH: Finding Bugs in Bash Scripts中提到它。
答案 0 :(得分:2)
grep -w -- ...
阻止了以下内容的解释 -
修改的
(我没看过最后一部分抱歉)。是的,这是唯一的方法。另一种方法是避免将其作为搜索的第一部分;例如".{0}-x"
也有效,但很奇怪,例如。
grep -w ".{0}$1" ...
也应该有用。
答案 1 :(得分:2)
在这个脚本中实际上有另一个代码注入(或者你想要的任何代码)错误:它只是将grep
的输出交给[
(又名test
)命令,并假设如果它不为空则返回true。但是如果输出长度超过一个“单词”,[
会将其视为表达式并尝试对其进行评估。例如,假设文件包含行0 -eq 2
并且您搜索“0” - [
将确定0不等于2,并且脚本将打印为false,尽管它找到了一场比赛。
解决这个问题的最佳方法是使用Ignacio Vazquez-Abrams的建议(由Dennis Williamson澄清) - 这完全避免了解析问题,并且也更快(因为-q
使grep
停止在第一场比赛中搜索)。如果该选项不可用,另一种方法是使用双引号保护输出:if [ "$(grep -w -- "$1" "$FILE")" ]; then
(请注意,我还使用了$()而不是反引号,因为我发现它们更容易阅读和引用在$ FILE附近,以防它包含任何有趣的内容,如空格。
答案 2 :(得分:1)
虽然在这种特殊情况下不适用,但可以使用另一种技术来防止以连字符开头的文件名被解释为选项:
rm ./-x
或
rm /path/to/-x