在Java中反序列化不受信任的数据有什么安全影响?

mer*_*ike 11 java security serialization

反序列化不受信任的数据是否安全,前提是我的代码不对反序列化对象的状态或类进行假设,或者仅仅反序列化的行为是否会引起不希望的操作?

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

小智 7

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

代码注入

可以创建一个readObject实现任意字节码注入的大门.只需从流中读取一个字节数组并将其传递给(ClassLoader.defineClassClassLoader.resolveClass()参见前者后者的javadoc ).我不知道这种实现的用途是什么,但它是可能的.

记忆力耗尽

编写安全readObject方法很难.直到最近有点readObject方法HashMap包含以下行.

int numBuckets = s.readInt();
table = new Entry[numBuckets];
Run Code Online (Sandbox Code Playgroud)

这使得攻击者很容易通过几十个字节的序列化数据来分配几千兆字节的内存,这将使您的系统立即崩溃OutOfMemoryError.

当前实现Hashtable,似乎仍然容易受到类似的攻击; 它根据元素数量和负载因子计算分配数组的大小,但是没有防范不合理值的保护loadFactor,因此我们可以轻松地为表中的每个元素分配10亿个时隙.

CPU负载过大

修复漏洞HashMap是作为更改的一部分完成的,以解决与基于散列的映射相关的另一个安全问题.CVE-2012-2739描述了一种基于CPU消耗的拒绝服务攻击,它通过创建HashMap具有很多冲突密钥(即具有相同散列值的不同密钥)来实现.记录的攻击基于HTTP POST数据中的URL或密钥中的查询参数,但是a的反序列化HashMap也容易受到此攻击.

保障措施是投入HashMap,以防止这种类型的攻击都集中在与地图String键.这是足以防止基于HTTP的攻击,但很容易与反序列化规避,例如,通过每个包装StringArrayList(它的hashCode也是可预见的).Java 8包含一个提议(JEP-180),以进一步改善HashMap面对许多冲突的行为,这将保护扩展到所有实现的密钥类型Comparable,但仍然允许基于ArrayList密钥的攻击.

这样做的结果是,攻击者可以设计一个字节流,以便从该流中反序列化对象所花费的CPU工作量随着流的大小呈二次方式增长.

摘要

通过控制反序列化过程的输入,攻击者可以触发任何readObject反序列化方法的调用.理论上,这种方法可以允许字节码注入.实际上,以这种方式容易耗尽内存或CPU资源肯定是可能的,从而导致拒绝服务攻击.审核系统以防止此类漏洞非常困难:您必须检查每个实现readObject,包括第三方库和运行时库中的实现.