如何发现java反序列化问题?

时间:2010-11-01 11:42:36

标签: java serialization exploit

我希望能够发现java代码中的反序列化问题。我应该寻找什么?例如,如何判断某些java代码是否试图利用“java calendar bug”?请注意,我不是一个java程序员,但我理解序列化和OOP背后的概念。我正在尝试实施一些安全检查(类似于编译器警告工具)。

编辑:根据评论我想稍微改变一下这个问题: 我认为所有分析的代码都是“不可信的”,有没有办法评估潜在的危险?我的意思是,我可以告诉代码A在反序列化错误方面比B更危险吗?我应该寻找什么?

4 个答案:

答案 0 :(得分:5)

首先,您需要了解您的上下文以确定安全威胁。 (当我谈到“信任”时,我只是采取了一些捷径。我故意恶意说话。)

如果序列化数据是以相同的信任创建,保存和读取的,那么就没有任何实际问题(标准错误除外)。请注意,如果您编写任何敏感信息,那么序列化数据也是敏感的(这似乎很明显,但那里有相当多的间接信息)。

如果序列化数据因任何原因不受信任,那么还有一点需要考虑。重新创建的对象的内部结构可能是“不寻常的”。数据可能不一致。您可能共享了应该是可分离的可变对象。反序列化可能会导致无限循环,或者在宇宙热死亡之前恰好无法完成的非无限循环。当然,数据可能是谎言。

如果您正在编写由不太可信的代码使用的库代码,那么事情会变得更有趣:

在“日历错误”(和类似)的情况下,这是关于使用恶意数据和恶意代码对任意流进行反序列化。 Java安全编码指南建议在自定义readObject方法中进行安全检查(使用“Java2安全模型”),这意味着您不应该以比代码和数据更多的信任来调用反序列化。

从可反复使用的对象那边,事情变得更加棘手。 ObjectInputStreamreadObjectreadUnshareddefaultReadObjectreadFields或仅默认反序列化提供的对象可能包含恶意代码捕获的引用,或者非最终引用类,被恶意分类。在部分初始化时,也可以在反序列化期间使用对象。反序列化不会调用反序列化类的“真实”构造函数(readObject / readObjectNoData是一种伪构造函数,它不能设置final s)。这完全是一场噩梦,所以你可能不想让你的敏感类可以序列化。

序列化和反序列化的实施存在许多漏洞。你不需要担心这个,除非你自己实现它。

答案 1 :(得分:2)

嗯......你的问题有点笼统。你看过this文章了吗?这是关于Java的序列化算法,但是来自谷歌的缓存,因为主页似乎目前正在下降。

答案 2 :(得分:1)

我认为打败利用Java中已知安全漏洞的代码的最佳方法是升级到修复bug的Java版本。下一个最好的方法(处理序列化相关的错误)是将来自未知/未经验证/不安全来源的所有序列化数据视为可疑。

通过分析Java代码来发现安全漏洞,试图发现问题并不容易,需要深入了解正在使用和可能被利用的Java机制。试图发现尝试的攻击(一般情况下)会更加困难,特别是如果你正在寻找零日安全漏洞的漏洞。请记住,还有其他潜在的载体。

(如果有简单的方法可以在Java中找到未知的安全漏洞,可以打赌Sun和其他安全研究人员已经使用过它们。)

答案 3 :(得分:1)

如果序列化Java对象以将其传输到单独的应用程序,为什么不考虑使用应用程序之间共享的密钥对对象进行签名?它应该足以保护自己免受中间人攻击。

回到验证问题的核心,对于通用语言来说,验证非常困难。您应该查找有关此主题的科学出版物。我认为最常用的技术是sandboxing。第二种方法是限制语言并禁止执行危险命令,例如Yahoo Caja library使用这种技术。