为什么应该避免使用exec()和eval()?

2024-03-29 15:41:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我在多个地方多次看到过这种情况,但从来没有找到一个令人满意的解释,为什么会出现这种情况。

所以,希望这里会有一个。为什么我们(至少,通常)不应该使用exec()eval()

编辑:我看到人们认为这个问题与web服务器有关,但事实并非如此。我可以理解为什么传递给exec的未初始化字符串可能是不好的。它在非web应用程序中坏吗?


Tags: 字符串服务器web应用程序编辑地方eval情况
3条回答

通常有更清晰、更直接的方法来达到同样的效果。如果您构建一个复杂的字符串并将其传递给exec,则代码很难遵循,也很难测试。

示例:我编写了读取字符串键和值并在对象中设置相应字段的代码。看起来是这样的:

for key, val in values:
    fieldName = valueToFieldName[key]
    fieldType = fieldNameToType[fieldName]
    if fieldType is int:
        s = 'object.%s = int(%s)' % (fieldName, fieldType) 
    #Many clauses like this...

exec(s)

这段代码对于简单的情况来说并不可怕,但是随着新类型的出现,它变得越来越复杂。当出现错误时,它们总是在调用exec时触发,因此堆栈跟踪无法帮助我找到它们。最后,我换了一个稍微长一点、不那么聪明的版本,它显式地设置了每个字段。

代码清晰性的第一条规则是,代码的每一行都应该通过只查看其附近的行而易于理解。这就是为什么不鼓励使用goto和全局变量。exec和eval很容易严重违反这个规则。

当你需要执行官和评估官的时候,是的,你真的需要他们。

但是,这些函数(以及其他脚本语言中类似的构造)的大多数在野外使用是完全不合适的,可以用其他更简单的构造来代替,这些构造更快、更安全,并且bug更少。

您可以通过适当的转义和过滤,安全地使用exec和eval。但是那种直接使用exec/eval来解决问题的编码程序(因为他们不理解语言提供的其他功能)并不是那种能够正确处理的编码程序;而是那种不理解字符串处理并盲目地连接子字符串的编码程序,导致脆弱的不安全代码。

这是弦的诱惑。把字符串段放在周围看起来很容易,而且愚蠢的程序员会认为他们理解自己在做什么。但经验表明,在某些角落(或不是这样的角落)的情况下,结果几乎总是错误的,往往具有潜在的安全隐患。这就是为什么我们说eval是邪恶的。这就是为什么我们说HTML的正则表达式是邪恶的。这就是我们推动SQL参数化的原因。是的,你可以通过手动字符串处理来解决这些问题。。。但除非你已经明白我们为什么这么说,否则你很可能不会。

eval()和exec()可以促进惰性编程。更重要的是,它表明正在执行的代码可能没有在设计时编写,因此没有经过测试。换句话说,如何测试动态生成的代码?尤其是跨浏览器。

相关问题 更多 >