在这种情况下,是否存在任何安全漏洞:
eval(repr(unsanitized_user_input), {"__builtins__": None}, {"True":True, "False":False})
其中unsanitized_user_input
是str对象。这个字符串是用户生成的,可能很讨厌。假设我们的web框架没有让我们失望,它是Python内置的一个真正诚实的str实例。在
如果这很危险,我们能对输入做些什么来保证它的安全吗?在
我们绝对不想执行字符串中包含的任何内容。在
另请参见:
更大的背景(我相信)对这个问题并不重要,那就是我们有数以千计的:
^{pr2}$在某些情况下,嵌套:
repr([[unsanitized_user_input_1,
unsanitized_user_input_2],
[unsanitized_user_input_3,
unsanitized_user_input_4],
...])
它们本身用repr()
转换为字符串,放入持久存储器,最后用eval读回内存。在
Eval从持久存储中反序列化字符串的速度比pickle和simplejson快得多。json和ast都不可用。不允许使用C模块,也不允许使用cPickle。在
这确实很危险,最安全的替代方法是
ast.literal_eval
(请参阅标准库中的ast模块)。当然,您可以构建和修改ast
,以便在计算结果AST之前提供变量的求值等(当它是文本时)。在对
eval
的可能攻击从它能得到它的任何对象开始(这里说True
),然后经过.uu类到它的类型对象,等等,直到object
,然后得到它的子类。。。基本上,它可以达到任何对象类型和破坏浩劫。我可以说得更具体一些,但我不想在公共论坛上这样做(这个漏洞是众所周知的,但是考虑到有多少人仍然忽视它,把它透露给想要脚本的孩子可能会让事情变得更糟。。。只需避免eval
未经确认的用户输入,从此过上幸福的生活!-). 在如果您可以毫无疑问地证明
unsanitized_user_input
是一个来自Python内置的str
实例,那么这总是安全的。{3}实际上,所有这些对象都是安全的。你放了一根绳子,你就得到了一根绳子。你所做的就是逃走,把它找出来。在这一切让我认为
eval(repr(x))
不是你想要的——除非有人给你一个看起来像字符串但不是字符串的unsanitized_user_input
对象,否则不会执行任何代码,但这是另一个问题——除非你试图以最慢的方式复制字符串实例:D正如您所描述的,从技术上讲,评估repred字符串是安全的,但是,无论如何我都会避免这样做,因为这会带来麻烦:
可能会出现一些奇怪的情况,您假设只存储已重复的字符串(例如,错误/进入存储的不同路径不会立即报告,这会成为代码注入漏洞,否则可能无法利用)
即使现在一切正常,假设也可能在某个时刻发生变化,未定义的数据可能会被不知道eval代码的人存储在该字段中。
正如Alex Martelli指出的,在python2.6及更高版本中,有ast.literal_评估它可以安全地处理字符串和其他简单的数据类型,如元组。这可能是最安全和最完整的解决方案。在
然而,另一种可能是使用
string-escape
编解码器。这比eval快得多(根据timeit,大约是eval的10倍),在早期版本中比literal_eval可用,并且应该执行您想要的操作:([1:-1]将去掉repr添加的外部引号。)
相关问题 更多 >
编程相关推荐