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