在Java中反序列化不可信数据的安全影响是什么?

前端之家收集整理的这篇文章主要介绍了在Java中反序列化不可信数据的安全影响是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我的代码对反序列化对象的状态或类没有任何假设,或者只是反序列化的行为会导致不期望的操作,那么可以安全地反序列化不受信任的数据吗?

(威胁模型:攻击者可以自由修改序列化数据,但这是他能做的)

解决方法

反序列化本身已经可以不安全了.一个可序列化的类可以定义一个readObject方法(参见 specification),当这个类的对象将从流反序列化时被调用.攻击者无法提供此代码,但使用精心设计的输入,可以使用任何输入来调用类路径中的任何此类readObject方法.

代码注入

可以使一个readObject实现打开任意字节码注入的门.只需从流中读取一个字节数组,并将其传递给ClassLoader.defineClass和ClassLoader.resolveClass()(参见the formerthe later的javadoc).我不知道这种实现的用途是什么,但是这是可能的.

记忆疲惫

编写安全的readObject方法很难.直到somewhat recently,HashMap的readObject方法包含以下几行.

int numBuckets = s.readInt();
table = new Entry[numBuckets];

这样一来,攻击者就可以轻松地分配几GB的内存,只需要几十个字节的序列化数据,这样就可以在任何时间内使用OutOfMemoryError来关闭系统.

Hashtable的current implementation似乎仍然容易受到类似的攻击;它基于元素的数量负载因子来计算分配的数组的大小,但是在loadFactor中没有对不合理的值进行保护,因此我们可以轻松地请求为表中的每个元素分配十亿个时隙.

cpu负载过大

修复HashMap中的漏洞是作为更改的一部分,以解决与基于散列的地图相关的另一个安全问题. CVE-2012-2739通过创建具有非常多的冲突键(即具有相同哈希值的不同键)的HashMap来描述基于cpu消耗的拒绝服务攻击.记录的攻击基于HTTP POST数据中的URL或密钥中的查询参数,但是HashMap的反序列化也容易受到此攻击的影响.

放在HashMap中以防止这种类型的攻击的safeguards集中在使用String键的地图上.这足以防止基于HTTP的攻击,但很容易绕过反序列化,例如通过用ArrayList(其hashCode也是predictable)包装每个String. Java 8包括一个提案(JEP-180),以进一步改善HashMap在面临许多冲突时的行为,将保护扩展到实现Comparable的所有关键类型,但仍然允许基于ArrayList键的攻击.

这样做的结果是,攻击者可以设计一个字节流,使得从该流反序列化对象所需的cpu工作量随着流的大小而二次增长.

概要

通过控制反序列化过程的输入,攻击者可以触发任何readObject反序列化方法调用.理论上这种方法可以允许字节码注入.实际上,这样可以轻松地耗尽内存或cpu资源,导致拒绝服务攻击.审查您的系统是否存在这种漏洞非常困难:您必须检查readObject的每个实现,包括第三方库和运行时库中的所有实现.

猜你在找的Java相关文章