Python 'eval'函数在列表反序列化中的安全性

10 浏览
0 Comments

Python 'eval'函数在列表反序列化中的安全性

在这种情况下会发生任何安全漏洞吗:

eval(repr(unsanitized_user_input), {"__builtins__": None}, {"True":True, "False":False})

其中unsanitized_user_input是一个字符串对象。该字符串是由用户生成的,可能很糟糕。假设我们的Web框架没有失效,它是真正的Python内置字符串实例。

如果这很危险,我们能否对输入进行任何处理以使其安全?

我们绝不想执行字符串中包含的任何内容。

另请参见:

我相信这不是问题的基本内容,我们有成千上万个这样的:

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。

admin 更改状态以发布 2023年5月21日
0
0 Comments

如果你能证明 unsanitized_user_input 是Python内置的 str 实例,且没有被篡改,那么这就是安全的。实际上,即使没有那些额外的参数,它也是安全的,因为对于所有这样的字符串对象,eval(repr(astr)) = astr。你输入一个字符串,你得到一个字符串,你所做的只是转义和还原它。

所有这些都让我想到 eval(repr(x)) 不是你想要的东西——除非有人给你一个看起来像字符串但实际上不是字符串的 unsanitized_user_input 对象,但那是另外一个问题——除非你试图以最慢的方式复制一个字符串实例 :D。

0
0 Comments

确实很危险,最安全的替代方案是ast.literal_eval(请参阅标准库中的ast模块)。当然,您可以构建和修改一个ast,以提供例如在评估结果AST(当变量等减少到文字)之前对其进行计算等的功能。

eval可能的漏洞始于它所能获取的任何对象(例如这里的True),并通过.__class_到其类型对象等一直到object,然后获取其子类……基本上它可以获得任何对象类型并造成破坏。我可以更具体,但我不想在公共论坛上这样做(该漏洞众所周知,但考虑到仍有多少人忽略它,将其透露给想要成为脚本小子的人可能会使事情变得更糟……只需避免在未经过滤的用户输入上使用eval,就可以幸福地生活!)。

0