是否有可能发生在这种情况下,任何安全漏洞:
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的是不允许的。
这的确是危险的,最安全的办法是ast.literal_eval
(见AST标准库模块)。 当然,你可以创建和修改的ast
你EVAL产生的AST之前提供的变量,如评估等等(当它下降到面值)。
可能利用的eval
与任何对象开始就可以得到它的手(说True
在这里),并通过.__ class_其类型的对象,等等,直到去object
,然后获取它的子类...基本上它可以让任何对象类型和破坏的破坏。 我可以更具体,但我宁愿不这样做在一个公开论坛(该漏洞是众所周知的,但考虑到有多少人还忽略它,揭示它想当脚本小子可能使事情变得更糟......只是避免eval
上unsanitized用户输入和生活幸福快乐的日子 - !)。
如果你能证明毫无疑问, unsanitized_user_input
是str
从Python内建有没有篡改实例,那么这始终是安全的。 事实上,它甚至会没有所有这些额外的参数,因为是安全eval(repr(astr)) = astr
所有这类字符串对象。 你把一个字符串,你回来了一个字符串。 所有你所做的就是逃跑,未逸出它。
这一切都使我认为eval(repr(x))
是不是你想要的-除非有人给你的任何代码都不会被执行unsanitized_user_input
对象,看起来像一个字符串,但不大,但是这是一个不同的问题--unless你想为一个字符串比如在可能的最慢的方式复制:d。
随着一切都象你所说的,它在技术上是安全的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]是剥去外引号再版增加)。
一般来说,你应该绝不允许任何人发布的代码。
所谓的“有偿专业程序员”有困难,有足够的时间写一些实际的工作代码。
从匿名公众接受的代码 - 没有正式的QA的好处 - 是最坏的所有可能出现的情况。
专业的程序员 - 没有良好的,坚实的正式QA - 将使几乎所有网站的哈希值。 事实上,我在逆向工程从有偿专业人员一些令人难以置信的恶意代码。
通过QA支配 - - 允许非专业的想法发布的代码是真正可怕的。
repr([unsanitized_user_input_1, unsanitized_user_input_2, ...
... unsanitized_user_input
是str
对象
你不应该序列化的字符串将它们存储在数据库中..
如果这些都是字符串,如你所提到的-为什么你就不能存储在一个字符串db.StringListProperty
?
嵌套条目可能会更复杂一些,但为什么是这样的话? 当你不得不求助于EVAL从数据库中获取数据,你可能做错事..
你不能存储每个unsanitized_user_input_x
,因为它是自己的db.StringProperty
行,由基准场有他们组?
无论是那些可能并不适用,因为我不知道你想达到什么样的,但我的观点是-你能不能构建的方式将数据你在哪里不必依靠eval
(也依赖它不是一个安全问题)?