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

发布于 2024-09-05 06:00:16 字数 762 浏览 8 评论 0原文

我编写了一个名为“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:寻找中发现了它Bash 脚本中的错误

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尘世孤行 2024-09-12 06:00:16

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

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

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).

若沐 2024-09-12 06:00:16
grep -w -- ...

防止在接下来的内容中进行这种解释——

编辑

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

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

也应该可以工作。

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.

九八野马 2024-09-12 06:00:16

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

rm ./-x

rm /path/to/-x

Though not applicable in this particular case, another technique can be used to prevent filenames that start with hyphens from being interpreted as options:

rm ./-x

or

rm /path/to/-x
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文