如何防止bash脚本中的代码/选项注入

时间:2010-06-10 08:44:31

标签: bash options code-injection

我编写了一个名为“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

打破了脚本,因为-xgrep解释为一个选项。 所以我改进了我的脚本

#!/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中提到它。

3 个答案:

答案 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