使用 `eval echo` 总是安全的吗?

Cyk*_*ker 21 bash echo

eval通常不鼓励使用,因为它允许执行任意代码。但是,如果我们使用eval echo,那么看起来字符串的其余部分将成为 的参数,echo因此它应该是安全的。我在这方面正确吗?

Cel*_*ada 40

反例:

DANGEROUS=">foo"
eval echo $DANGEROUS
Run Code Online (Sandbox Code Playgroud)

的任意参数echo可能会做一些比创建一个名为“foo”的文件更邪恶的事情。

  • 另外:`DANGEROUS="hello;ls"`,用于代替 `ls` 的任意命令。 (6认同)
  • 另外:`DANGEROUS='$(ls)'`(可能需要更多的转义)。 (2认同)

Cyk*_*ker 26

@Celada 提供了一个很好的答案。为了证明eval真的很邪恶,这里有一些比创建一个名为“foo”的文件更邪恶东西

DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"
Run Code Online (Sandbox Code Playgroud)

当然,还有比创建名为 "foo" 的文件更邪恶的事情

  • +1 证明引用像 `"$THIS"` 这样的变量而不是像 `$THIS` 这样的变量甚至没有帮助! (8认同)

ImH*_*ere 12

不,它并不总是安全的。eval 可以执行任何命令。

一个安全的命令,像这样(日期不执行,因为它在单引号内):

$ echo '$(date)'
$(date)
Run Code Online (Sandbox Code Playgroud)

如果与 eval 一起使用会变得危险:

$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016
Run Code Online (Sandbox Code Playgroud)

当然,日期可以是任何命令。

改进这一点的一种方法是额外引用 eval 的参数:

$ eval echo '\$(date)'
$(date)
Run Code Online (Sandbox Code Playgroud)

但是通常很难正确引用一个表达式两次。

如果表达式可以由外部攻击者设置,则无法控制正确的引用,例如:

$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!
Run Code Online (Sandbox Code Playgroud)