【问题标题】:How to prevent code/option injection in a bash script如何防止 bash 脚本中的代码/选项注入
【发布时间】:2010-06-10 08:44:31
【问题描述】:

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

【问题讨论】:

  • 为什么在[ 中使用反引号而不是直接使用grep -q
  • 我尝试了您的建议,但 if [ grep -q -w -- "$1" $ACCOUNTS_DGRID ]; 对我不起作用。我收到./isinFile.sh: line 5: [: too many arguments 之类的错误
  • 他的意思也没有方括号:if grep -q -w -- "$1" $ACCOUNTS_DGRID
  • 好的,我明白了。所以对 Ignacio 评论的回答是,我不知道 grep-q 选项。谢谢你的提示!但是与我的版本相比,使用grep -q 的优势是什么?我仍然必须使用-- 来防止选项注入。

标签: bash options code-injection


【解决方案1】:
grep -w -- ...

防止后面的解释--

编辑

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

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

应该也可以。

【讨论】:

  • 重要提示 {} 可用于扩展正则表达式,因此添加 -E 选项; (抱歉,我将 grep 别名为 grep -E 所以一开始没有注意到)
  • 您可以通过转义大括号在基本的正则表达式(至少在我测试的 grep 的实现中)中执行此操作:grep -w ".\{0\}$1" ...
  • 致 ShinTakezou:您是否还有其他描述 ---option 的参考资料?或者你知道描述--做什么的技术术语,所以你可以搜索它?
  • 通常是 *nix/*nix 类系统的常见做法,我认为这很常见,因为它是告诉 getopt() 停止解析选项的方法(getopt() 是一个 posix可用于解析参数的函数):常规,像往常一样:请参阅linux.die.net/man/3/getopt 并搜索句子«特殊参数“--”强制结束选项扫描,无论扫描模式如何。»
  • @Gordon Davisson:谢谢!但我发现 {} () + 等的解释很丑陋,更喜欢 -E 并认为它们很特别,如果我不希望它们特别,就必须逃避
【解决方案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 以防万一它包含任何有趣的东西,比如空格)。

【讨论】:

    【解决方案3】:

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

    rm ./-x
    

    rm /path/to/-x
    

    【讨论】:

    • 要以编程方式应用此修复程序,请使用类似:[ "${FILE:0:1} = - ] && FILE="./$FILE"(即,如果 FILE 以破折号开头,请在其前面添加 ./)。
    • @Gordon: Bash: [[ $FILE == -* ]] ...
    猜你喜欢
    • 1970-01-01
    • 2020-02-24
    • 2023-03-14
    • 2011-10-18
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    相关资源
    最近更新 更多