33

我正在编写一个将用户输入存储在对象中的网络应用程序。这个对象将被腌制。

用户是否有可能制作恶意输入,当对象未腌制时可能会做一些令人震惊的事情?

这是一个非常基本的代码示例,它忽略了封装等奇妙的原则,但集中体现了我正在查看的内容:

import pickle

class X(object):
    some_attribute = None

x = X()
x.some_attribute = 'insert some user input that could possibly be bad'

p = pickle.dumps(x)

# Can bad things happen here if the object, before being picked, contained
# potentially bad data in some_attribute?
x = pickle.loads(p)
4

3 回答 3

15

是的和不...

不 - 除非解释器或 pickle 模块存在错误,否则您不能通过 pickle 文本或类似的方式运行任意代码。除非eval稍后编辑腌制文本,或者您正在做一些事情,例如创建一个具有此数据中提到的类型的新对象。

是的 - 根据您稍后打算如何处理对象中的信息,用户可以做各种各样的事情。从 SQL 注入尝试到更改凭据、暴力破解密码或在验证用户输入时应考虑的任何事情。但是您可能正在检查所有这些。


编辑

python文档说明了这一点:

警告 pickle 模块并非旨在防止错误或恶意构造的数据。永远不要取消从不受信任或未经身份验证的来源收到的数据。

然而这不是你的情况——你接受输入,通过常规验证,然后腌制它。

于 2012-04-23T14:14:51.700 回答
7

好吧,根据文档

警告:该pickle模块并非旨在防止错误或恶意构建的数据。永远不要取消从不受信任或未经身份验证的来源收到的数据。

这意味着如果数据结构存在于pickle算法将进入无法保证程序行为的状态的状态下,则可以仅通过调用它来攻击此功能。

根据这个网站

import pickle
pickle.loads("cos\nsystem\n(S'ls ~'\ntR.") # This will run: ls ~

是执行任意代码所需的全部内容。那里还有其他示例以及出于安全目的对酸洗的“改进”。

于 2012-04-23T14:23:28.400 回答
0

我在多处理模块的文档中发现了这一点,我认为它回答了这个问题:

警告

Connection.recv() 方法会自动取消接收到的数据,这可能会带来安全风险,除非您可以信任发送消息的进程。

因此,除非连接对象是使用 Pipe() 生成的,否则您应该只在执行某种身份验证后使用 recv() 和 send() 方法。请参阅身份验证密钥。

(强调我的)

结论是,如果连接对象使用受信任的管道(即受信任的pickle)生成的,那么它可以安全地解开。

于 2017-01-26T01:29:13.810 回答