Python的“EVAL”列表反序列化的安全(Safety of Python 'eval&

2019-06-25 15:36发布

是否有可能发生在这种情况下,任何安全漏洞:

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

其中unsanitized_user_input是一个STR对象。 该字符串是用户生成的,并可能是很讨厌。 假设我们的Web框架没有令我们失望,这是从Python内建一个真正的诚实,神海峡实例。

如果这是危险的,我们可以做任何事情来输入,使其安全吗?

我们绝对不想执行字符串中包含的任何东西。

也可以看看:

  • 有趣的博客帖子大约EVAL安全
  • 前一题
  • 博客: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反序列化从持久性存储的字符串长度超过咸菜和simplejson快得多。 解释器是Python 2.5的如此JSON和AST不可用。 没有C模块是允许的,cPickle的是不允许的。

Answer 1:

这的确是危险的,最安全的办法是ast.literal_eval (见AST标准库模块)。 当然,你可以创建和修改的ast你EVAL产生的AST之前提供的变量,如评估等等(当它下降到面值)。

可能利用的eval与任何对象开始就可以得到它的手(说True在这里),并通过.__ class_其类型的对象,等等,直到去object ,然后获取它的子类...基本上它可以让任何对象类型和破坏的破坏。 我可以更具体,但我宁愿不这样做在一个公开论坛(该漏洞是众所周知的,但考虑到有多少人还忽略它,揭示它想当脚本小子可能使事情变得更糟......只是避免eval上unsanitized用户输入和生活幸福快乐的日子 - !)。



Answer 2:

如果你能证明毫无疑问, unsanitized_user_inputstr从Python内建有没有篡改实例,那么这始终是安全的。 事实上,它甚至会没有所有这些额外的参数,因为是安全eval(repr(astr)) = astr所有这类字符串对象。 你把一个字符串,你回来了一个字符串。 所有你所做的就是逃跑,未逸出它。

这一切都使我认为eval(repr(x))是不是你想要的-除非有人给你的任何代码都不会被执行unsanitized_user_input对象,看起来像一个字符串,但不大,但是这是一个不同的问题--unless你想为一个字符串比如在可能的最慢的方式复制:d。



Answer 3:

随着一切都象你所说的,它在技术上是安全的EVAL repred琴弦,不过,我会避免这样做也无妨,因为它是自找麻烦:

  • 可能有一些奇怪的角落情况下你的假设,即只有repred字符串存储(例如一个bug /不同途径到不立即REPR存储becmes代码注入漏洞的地方,否则可能是不可利用)

  • 即使现在一切OK,假设可能在某个时刻发生变化,unsanitised数据可能会有人不知道的eval代码存储在这一领域。

  • 您的代码可能会得到重用(或更糟的是,复制粘贴+)到你没有考虑到的情况。

由于亚历马尔泰利指出,在python2.6的高,有ast.literal_eval这将安全处理字符串和其他简单的数据类型类似的元组。 这可能是最安全和最完整的解决方案。

然而,另一种可能性是使用string-escape编解码器。 这比EVAL快得多(根据timeit约10倍),在早期版本比literal_eval可用,应该做你想要什么:

>>> s = 'he\nllo\' wo"rld\0\x03\r\n\tabc'
>>> repr(s)[1:-1].decode('string-escape') == s
True

(该[1:-1]是剥去外引号再版增加)。



Answer 4:

一般来说,你应该绝不允许任何人发布的代码。

所谓的“有偿专业程序员”有困难,有足够的时间写一些实际的工作代码。

从匿名公众接受的代码 - 没有正式的QA的好处 - 是最坏的所有可能出现的情况。

专业的程序员 - 没有良好的,坚实的正式QA - 将使几乎所有网站的哈希值。 事实上,我在逆向工程从有偿专业人员一些令人难以置信的恶意代码。

通过QA支配 - - 允许非专业的想法发布的代码是真正可怕的。



Answer 5:

 repr([unsanitized_user_input_1, unsanitized_user_input_2, ... 

... unsanitized_user_inputstr对象

你不应该序列化的字符串将它们存储在数据库中..

如果这些都是字符串,如你所提到的-为什么你就不能存储在一个字符串db.StringListProperty

嵌套条目可能会更复杂一些,但为什么是这样的话? 当你不得不求助于EVAL从数据库中获取数据,你可能做错事..

你不能存储每个unsanitized_user_input_x ,因为它是自己的db.StringProperty行,由基准场有他们组?

无论是那些可能并不适用,因为我不知道你想达到什么样的,但我的观点是-你能不能构建的方式将数据你在哪里不必依靠eval (也依赖它不是一个安全问题)?



文章来源: Safety of Python 'eval' For List Deserialization
标签: python eval