使用“eval echo”总是安全的吗?

使用“eval echo”总是安全的吗?

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

答案1

反例:

DANGEROUS=">foo"
eval echo $DANGEROUS

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

答案2

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

DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"

当然也可以有比创建名为“foo”的文件更邪恶的事情

答案3

不,是不是永远安全。 eval 可以执行任何命令。

一个安全的命令,如下所示(日期不会被执行,因为它在单引号内):

$ echo '$(date)'
$(date)

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

$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016

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

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

$ eval echo '\$(date)'
$(date)

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

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

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

答案4

虽然确实总是eval需要谨慎对待,但eval echo建设并不总是毫无意义的,安全使用。我最近需要它来按照我需要完成的顺序评估多个大括号扩展。

bash从左到右进行多个大括号扩展,所以

xargs -I_ cat _/{11..15}/{8..5}.jpg

扩展到

xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg

但我需要先完成第二个支撑扩展,产生

xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg

我能想到的最好办法就是

xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)

这是有效的,因为单引号可以保护第一组大括号在解析eval命令行期间不被扩展,从而让它们由 调用的子 shell 扩展eval

可能有一些涉及嵌套大括号扩展的狡猾方案,可以让这种情况一步发生,但如果有的话,我太老了,太愚蠢了,看不到它。除此之外,还有其他 shellbash允许以更简洁的方式来实现这种事情。但无论如何,这种使用eval是安全的,因为它的参数都是不包含参数扩展的固定字符串。

相关内容