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

2024-11-27 10:42:00
admin
原创
164
摘要:问题描述:我已在多个地方多次见到过这种情况,但从未找到令人满意的解释来解释为什么会出现这种情况。因此,希望这里能介绍一个。为什么我们(至少一般情况下)不应该使用exec()和eval()?编辑:我看到人们假设这个问题与 Web 服务器有关 - 但事实并非如此。我明白为什么传递未经清理的字符串exec可能会很糟...

问题描述:

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

因此,希望这里能介绍一个。为什么我们(至少一般情况下)不应该使用exec()eval()

编辑:我看到人们假设这个问题与 Web 服务器有关 - 但事实并非如此。我明白为什么传递未经清理的字符串exec可能会很糟糕。在非 Web 应用程序中这很糟糕吗?


解决方案 1:

通常有更清晰、更直接的方法来实现相同的效果。如果你构建一个复杂的字符串并将其传递给 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 很容易严重违反此规则。

解决方案 2:

当您需要 exec 和 eval 时,是的,您确实需要它们。

但是,这些函数(以及其他脚本语言中的类似构造)的大部分实际使用是完全不合适的,可以用其他更快、更安全、错误更少的更简单构造来代替。

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

这就是字符串的诱惑。随意使用字符串段看起来很容易,并且会愚弄天真的程序员,让他们以为自己明白自己在做什么。但经验表明,在某些极端情况下(或不那么极端的情况下),结果几乎总是错误的,而且往往存在潜在的安全隐患。这就是为什么我们说 eval 是邪恶的。这就是为什么我们说 regex-for-HTML 是邪恶的。这就是为什么我们推动 SQL 参数化。是的,您可以通过手动字符串处理正确完成所有这些事情……但除非您已经理解我们为什么这么说,否则您很可能不会理解

解决方案 3:

除了安全性之外,eval它们exec通常由于其引起的复杂性而被标记为不受欢迎。当您看到一个eval调用时,您通常不知道它背后到底发生了什么,因为它对通常位于变量中的数据起作用。这使得代码更难阅读。

调用解释器的全部功能是一种重型武器,只应在非常棘手的情况下使用。然而,在大多数情况下,最好避免这样做,而应使用更简单的工具。

话虽如此,但像所有概括一样,要小心这一点。在某些情况下,exec 和 eval 可能很有价值。但你必须有充分的理由使用它们。请参阅这篇文章,了解一种可接受的用法。

解决方案 4:

eval()并且exec()会助长懒惰编程。更重要的是,它表明正在执行的代码可能不是在设计时编写的,因此未经测试。换句话说,你如何测试动态生成的代码?尤其是跨浏览器。

解决方案 5:

与此处大多数答案所说的相反,exec 实际上是在 Python 中构建超完整装饰器的方法的一部分,因为您可以完全复制有关装饰函数的所有内容,从而为文档等目的生成相同的签名。它是广泛使用的装饰器模块 ( http://pypi.python.org/pypi/decorator/ ) 功能的关键。exec/eval 必不可少的其他情况是构建任何类型的“解释型 Python”应用程序时,例如 Python 解析的模板语言(如 Mako 或 Jinja)。

因此,这些函数的存在并不代表应用程序或库存在“不安全”的问题。以简单的 javascripty 方式使用它们来评估传入的 JSON 或其他内容,是的,这非常不安全。但一如既往,这完全取决于您使用它的方式,而这些都是非常重要的函数。

解决方案 6:

在可能运行用户输入的环境中允许这些功能是一个安全问题,而且实际起作用的清理器很难编写。

解决方案 7:

我过去曾使用过eval()(现在仍然时不时地使用)在快速而粗糙的操作过程中处理数据。它是可用于完成工作的工具包的一部分,但绝不能用于您计划在生产中使用的任何东西,例如任何命令行工具或脚本,因为其他答案中提到了所有原因。

你不能相信你的用户会做正确的事情。在大多数情况下,他们会这样做,但你必须期望他们做所有你从未想过的事情,并发现所有你从未预料到的错误。这正是eval()从工具变成负担的地方。

一个完美的例子是使用 Django 构建QuerySet。传递给查询的参数接受关键字参数,如下所示:

results = Foo.objects.filter(whatever__contains='pizza')

如果您以编程方式分配参数,您可能会考虑执行如下操作:

results = eval("Foo.objects.filter(%s__%s=%s)" % (field, matcher, value))

但是总有一种不使用的更好方法eval(),即通过引用传递字典:

results = Foo.objects.filter( **{'%s__%s' % (field, matcher): value} ) 

通过这种方式,不仅性能更快,而且更安全、更符合 Python 风格。

这个故事的寓意是什么?

对于小任务、测试和真正临时的事情来说,使用eval()可以的,但对于永久使用来说却是不利的,因为几乎肯定总有更好的方法来完成它!

解决方案 8:

出于同样的原因,您不应该以 root 身份登录:这样很容易弄巧成拙。

解决方案 9:

请勿尝试在您的计算机上执行以下操作:

s = "import shutil; shutil.rmtree('/nonexisting')"
eval(s)

现在假设某人可以从 Web 应用程序控制 s。

解决方案 10:

原因#1:一个安全漏洞(即编程错误……我们不能声称这些错误可以避免)并且您刚刚授予用户访问服务器 shell 的权限。

解决方案 11:

在交互式解释器中尝试这个并看看会发生什么:

>>> import sys
>>> eval('{"name" : %s}' % ("sys.exit(1)"))

当然,这只是一个极端情况,但防止此类事情发生可能很棘手。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2545  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1551  
  建筑工程全生命周期涉及从项目规划、设计、施工到运营维护等多个复杂阶段,每个阶段都产生和依赖大量信息。PLM(产品生命周期管理)系统作为一种整合数据、流程和人员的数字化解决方案,正逐渐成为建筑行业实现高效协同与可持续发展的关键支撑。通过数字化转型,PLM系统能够优化各阶段的工作流程,提升项目整体质量和效率,为建筑工程的全...
plm是什么软件   1  
  产品生命周期管理(PLM)系统在企业资源成本率优化方面发挥着至关重要的作用。通过构建有效的数据模型,PLM系统能够整合企业各个环节的数据,为资源成本的精准分析和优化提供有力支持。这不仅有助于企业降低成本,还能提升产品质量和市场竞争力。PLM系统概述PLM系统是一种用于管理产品从概念设计到退役全生命周期过程中所有信息和流...
PLM项目管理软件   1  
  产品生命周期管理(PLM)系统在现代企业的产品研发、生产与管理过程中扮演着至关重要的角色。它整合了从产品概念设计到产品退役的全生命周期数据与流程,助力企业提升效率、降低成本并增强创新能力。随着技术的不断发展,到 2025 年,PLM 系统将具备一系列核心功能模块,这些模块将深度影响企业的运营与发展。产品数据管理模块产品...
plm是什么意思   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用