在这种情况下是否存在任何可能发生的安全漏洞:
eval(repr(unsanitized_user_input), {"__builtins__": None}, {"True":True, "False":False})
Run Code Online (Sandbox Code Playgroud)
unsanitized_user_input
str对象在哪里.字符串是用户生成的,可能很讨厌.假设我们的Web框架没有让我们失望,那么它就是来自Python内置的一个真正的诚实的str实例.
如果这很危险,我们可以对输入做任何事情以使其安全吗?
我们当然不希望执行字符串中包含的任何东西.
也可以看看:
(我相信)对这个问题不重要的更大背景是我们有成千上万的这些:
repr([unsanitized_user_input_1,
unsanitized_user_input_2,
unsanitized_user_input_3,
unsanitized_user_input_4,
...])
Run Code Online (Sandbox Code Playgroud)
在某些情况下嵌套:
repr([[unsanitized_user_input_1,
unsanitized_user_input_2],
[unsanitized_user_input_3,
unsanitized_user_input_4],
...])
Run Code Online (Sandbox Code Playgroud)
它们本身转换为字符串repr()
,放入持久存储,最后用eval读回内存.
Eval从持久存储中反序列化字符串比pickle和simplejson快得多.解释器是Python 2.5所以json和ast不可用.不允许使用C模块,不允许使用cPickle.
如果你可以毫无疑问地证明这unsanitized_user_input
是str
Python内置函数中没有被篡改的实例,那么这总是安全的.事实上,即使没有所有这些额外的参数,它也是安全的,因为eval(repr(astr)) = astr
对于所有这样的字符串对象.你输入一个字符串,你得到一个字符串.你所做的一切都是逃避并且不受欢迎.
这一切都让我觉得这eval(repr(x))
不是你想要的 - 没有代码会被执行除非有人给你一个unsanitized_user_input
看起来像字符串的对象但不是,但这是一个不同的问题 - 除非你试图以尽可能最慢的方式复制字符串实例:D.
对于您描述的所有内容,评估 repred 字符串在技术上是安全的,但是,无论如何我都会避免这样做,因为它会带来麻烦:
可能存在一些奇怪的极端情况,您假设只存储了重复的字符串(例如,一个错误/不同的进入存储的路径不会立即重复成为代码注入漏洞,否则它可能无法利用)
即使现在一切正常,假设可能会在某个时候发生变化,并且未经处理的数据可能会被不知道 eval 代码的人存储在该字段中。
您的代码可能会被重用(或更糟的是,复制+粘贴)到您没有考虑过的情况。
正如Alex Martelli指出的那样,在 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
Run Code Online (Sandbox Code Playgroud)
( [1:-1] 是去除 repr 添加的外部引号。)
归档时间: |
|
查看次数: |
3100 次 |
最近记录: |