避免 Java 序列化!

Java 中的序列化允许我们将对象转换为字节流。此字节流可以保存到磁盘或传输到另一个系统。反之,字节流可以反序列化并允许我们重新创建原始对象。

最大的问题在于反序列化部分。通常它看起来像这样:

ObjectInputStream in = new ObjectInputStream( inputStream );
return (Data)in.readObject();

在解码之前,无法知道您正在反序列化什么。攻击者可能序列化了一个恶意对象并将其发送到您的应用程序。一旦您调用readObject(),恶意对象就已被实例化。您可能认为这些类型的攻击是不可能的,因为您需要在类路径上有一个易受攻击的类。但是,如果您考虑类路径上的类数量(包括您自己的代码、Java 库、第三方库和框架),则很可能存在一个易受攻击的类。

Java 序列化也被称为“不断给予的礼物”,因为它多年来产生了许多问题。Oracle 计划最终将 Java 序列化作为 Project Amber 的一部分删除。但是,这可能需要一段时间,并且不太可能在以前的版本中修复。因此,尽可能避免使用 Java 序列化是明智的。如果您需要serializable在域实体上实现,最好实现自己的readObject(),如下所示。这可以防止反序列化。

private final void readObject(ObjectInputStream in) throws java.io.IOException {
   throw new java.io.IOException("Deserialized not allowed");
}

如果您需要自己反序列化输入流,则应使用有限制的。Apache Commons IOObjectsInputStream就是一个很好的例子。这会检查反序列化的对象是否被允许。ValidatingObjectInputStreamObjectInputStream

FileInputStream fileInput = new FileInputStream(fileName);
ValidatingObjectInputStream in = new ValidatingObjectInputStream(fileInput);
in.accept(Foo.class);

Foo foo_ = (Foo) in.readObject();

对象反序列化问题并不局限于 Java 序列化。从 JSON 反序列化到 Java 对象也存在类似的问题。博客文章“Jackson 反序列化漏洞”中有一个关于 Jackson 库的反序列化问题的示例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值