在这种情况下是否会发生任何安全漏洞:
eval(repr(unsanitized_user_input), {"__builtins__": None}, {"True":True, "False":False})
其中 unsanitized_user_input
是一个 str 对象。该字符串是用户生成的,可能很讨厌。假设我们的 Web 框架没有让我们失望,它是来自 Python 内置函数的真正诚实的 str 实例。
如果这很危险,我们可以对输入采取任何措施以使其安全吗?
我们绝对不想执行字符串中包含的任何内容。
另见:
(我相信)对这个问题来说并不重要的更大的背景是我们有成千上万的这样的:
repr([unsanitized_user_input_1,
unsanitized_user_input_2,
unsanitized_user_input_3,
unsanitized_user_input_4,
...])
在某些情况下嵌套:
repr([[unsanitized_user_input_1,
unsanitized_user_input_2],
[unsanitized_user_input_3,
unsanitized_user_input_4],
...])
它们本身通过 repr()
转换为字符串,放入持久存储中,并最终通过 eval 读回内存。
Eval 从持久存储中反序列化字符串比 pickle 和 simplejson 快得多。解释器是 Python 2.5,所以 json 和 ast 不可用。不允许使用 C 模块,也不允许使用 cPickle。
最佳答案
这确实很危险,最安全的选择是 ast.literal_eval
(参见标准库中的 ast 模块)。您当然可以构建和更改 ast
以提供例如在评估结果 AST 之前评估变量等(当它归结为文字时)。
eval
的可能利用从它可以得到的任何对象开始(在这里说 True
),然后通过 .__class_ 到它的类型对象,等等。 object
,然后获取它的子类...基本上它可以获取任何对象类型并造成破坏。我可以更具体一些,但我宁愿不在公共(public)论坛上这样做(这个漏洞是众所周知的,但考虑到有多少人仍然忽视它,将它透露给想成为脚本小子的人可能会让事情变得更糟......只是避免 对未经过滤的用户输入进行评估
,从此过上幸福的生活!-)。
关于python - 用于列表反序列化的 Python 'eval' 的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1112665/