我希望能够发现 Java 代码中的反序列化问题。我应该寻找什么?例如,如何确定某些 java 代码是否试图利用“ java calendar bug ”?请注意,我不是 Java 程序员,但我理解序列化和 OOP 背后的概念。我正在尝试实施一些安全检查(类似于编译器警告工具)。
编辑:根据评论,我想稍微改变一下问题:我认为所有分析的代码“不受信任”,有没有办法评估潜在危险?我的意思是,我能说代码 A 在反序列化错误方面比 B 更危险吗?我应该寻找什么?
我希望能够发现 Java 代码中的反序列化问题。我应该寻找什么?例如,如何确定某些 java 代码是否试图利用“ java calendar bug ”?请注意,我不是 Java 程序员,但我理解序列化和 OOP 背后的概念。我正在尝试实施一些安全检查(类似于编译器警告工具)。
编辑:根据评论,我想稍微改变一下问题:我认为所有分析的代码“不受信任”,有没有办法评估潜在危险?我的意思是,我能说代码 A 在反序列化错误方面比 B 更危险吗?我应该寻找什么?
首先,您需要了解您的上下文以确定安全威胁。(当我谈论“信任”时,我是在走捷径。我说的是故意恶意。)
如果以相同的信任创建、保存和读取序列化数据,那么就没有任何真正的问题(除了标准错误)。请注意,如果您编写任何敏感信息,那么序列化数据也是敏感的(看起来很明显,但那里有相当多的间接性)。
如果序列化数据由于某种原因不受信任,则需要考虑更多。重新创建的对象的内部结构可能是“不寻常的”。数据可能不一致。您可能共享了应该分开的可变对象。反序列化可能会导致一个无限循环,或者一个非无限循环,恰好在宇宙热寂之前无法完成。当然,这些数据可能是谎言。
如果您正在编写由不太受信任的代码使用的库代码,那么事情会变得更有趣:
在“日历错误”(和类似的)的情况下,这是关于反序列化带有恶意数据和恶意代码的任意流。Java 安全编码指南建议在自定义方法中进行安全检查(使用“Java2 安全模型”)readObject
,这意味着您不应以比代码和数据更信任的方式调用反序列化。
从可反序列化对象的角度来看,事情更加棘手。ObjectInputStream
through readObject
, readUnshared
,提供的对象defaultReadObject
,readFields
或者只是默认的反序列化可能具有被恶意代码捕获的引用,或者对于非最终类,被恶意子类化。当部分初始化时,也可以在反序列化期间使用对象。反序列化不会调用反序列化类的“真实”构造函数(readObject
/readObjectNoData
是一种伪构造函数,不能设置final
s)。这有点像一场噩梦,所以你可能不想让你的敏感类可序列化。
在序列化和反序列化的实现中存在许多漏洞。你真的不需要担心这个,除非你自己实现它。
嗯……你的问题有点笼统。你看过这篇文章吗?这是关于 Java 的序列化算法,但来自 Google 的缓存,因为目前主页似乎已关闭。
我曾认为击败利用 Java 中已知安全漏洞的代码的最佳方法是升级到修复错误的 Java 版本。下一个最好的方法(处理与序列化相关的错误)是将来自未知/未经验证/不安全来源的所有序列化数据视为可疑。
试图通过分析 Java 代码的安全漏洞来发现问题并不容易,并且需要深入了解正在使用和可能被利用的 Java 机制。试图发现尝试的漏洞(通常)会更加困难,特别是如果您正在寻找针对零日安全漏洞的漏洞。请记住,还有其他潜在的载体。
(如果有找到 Java 中未知安全漏洞的简单方法,您可以打赌 Sun 和其他安全研究人员已经使用它们了。)
如果您序列化您的 Java 对象以将其传输到单独的应用程序,为什么不考虑使用在应用程序之间共享的密钥对对象进行签名呢?它应该足以保护自己免受中间人攻击。
回到验证问题的核心,通用语言的验证极其困难。你应该寻找关于这个主题的科学出版物。我认为最常用的技术是沙盒。第二种方法是限制语言并禁止执行危险命令,例如,Yahoo Caja 库就使用了这种技术。