3

我编写了一个名为“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中提到过。

4

3 回答 3

2
grep -w -- ...

在下文中阻止了这种解释——

编辑

(对不起,我没有阅读最后一部分)。是的,这是唯一的方法。另一种方法是避免将其作为搜索的第一部分;例如".{0}-x"也可以,但是很奇怪。,例如

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

也应该工作。

于 2010-06-10T08:48:42.670 回答
2

在这个脚本中实际上还有另一个代码注入(或任何你想调用的)错误:它只是将输出grep传递给[(aka test) 命令,并假设如果它不为空,它将返回 true。但是如果输出的长度超过一个“单词”,[则会将其视为表达式并尝试对其进行评估。例如,假设文件包含该行0 -eq 2并且您搜索“0” -[将确定 0 不等于 2,并且脚本将打印 false,尽管它找到了匹配项。

解决此问题的最佳方法是使用 Ignacio Vazquez-Abrams 的建议(由 Dennis Williamson 澄清)——这完全避免了解析问题,而且速度更快(因为在第一次匹配-qgrep停止搜索)。如果该选项不可用,另一种方法是用双引号保护输出:(if [ "$(grep -w -- "$1" "$FILE")" ]; then请注意,我还使用了 $() 而不是反引号,因为我发现它们更容易阅读,并且在 $FILE 周围加上引号如果它包含任何有趣的东西,比如空格)。

于 2010-06-11T03:07:25.003 回答
1

虽然不适用于这种特殊情况,但可以使用另一种技术来防止以连字符开头的文件名被解释为选项:

rm ./-x

或者

rm /path/to/-x
于 2010-06-10T12:53:25.697 回答