我正在编写一个将用户输入存储在对象中的Web应用程序。这个对象将被腌制。
用户是否有可能制作恶意输入,当对象被打开时,这些输入可能会造成一些恶劣的事情?
这是一个非常基本的代码示例,它忽略了封装等精彩原则,但却体现了我所看到的内容:
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)
答案 0 :(得分:15)
是,不......
否 - 除非解释器或pickle模块存在错误,否则您无法通过pickle文本或类似的东西运行任意代码。除非腌制文本稍后eval
,否则你正在做一些事情,比如用这个数据中提到的类型创建一个新对象。
是 - 根据您计划稍后对象中的信息,用户可以执行各种操作。从SQL注入尝试到更改凭据,强制密码破解或在验证用户输入时应考虑的任何事项。但你可能正在检查这一切。
修改:
python文档说明了这一点:
警告pickle模块不能防止错误或恶意构造的数据。切勿取消从不受信任或未经身份验证的来源收到的数据。
然而,这不是你的情况 - 你接受输入,通过常规验证,然后腌制它。
答案 1 :(得分:8)
警告:
pickle
模块无意对抗错误或恶意构造的数据。切勿取消从中收到的数据 不受信任或未经认证的来源。
如果数据结构存在于pickle算法将进入无法保证程序行为的状态的情况下,那么仅仅通过调用它就可以攻击这个功能。
根据此site
import pickle
pickle.loads("cos\nsystem\n(S'ls ~'\ntR.") # This will run: ls ~
是执行任意代码所需的全部内容。为了安全起见,还有其他的例子以及酸洗的“改进”。
答案 2 :(得分:0)
我在the documentation of multiprocessing module中找到了这个问题,我认为这个问题可以回答:
警告
Connection.recv()方法自动取消对数据的取消 收到,这可能是一个安全风险,除非你可以信任 发送消息的过程。
因此,除非使用Pipe()生成连接对象,否则 应该只在执行一些后使用recv()和send()方法 一种身份验证。请参阅验证密钥。
(强调我的)
结论是,如果使用受信任的管道(即受信任的pickle)生成连接对象 ,则可以安全地对其进行打开。