FlawOpen

flawopen.com/Java 反序列化/ObjectInputStream 安全

ObjectInputStream 能安全处理不可信数据吗?

Java 安全参考
通俗解释

通常不安全:readObject() 会重建 Java 对象,并可能调用类定义的反序列化方法。就像接收一份表单,却允许附件执行自带指令。恶意数据流可能触发应用中已有类的行为。是否执行代码取决于类、依赖库、可达路径和输入边界;并非每次调用都会触发。

有风险:原生对象反序列化
// 不要在此传入攻击者可控字节。
try (var in = new ObjectInputStream(untrustedStream)) {
    Object value = in.readObject();
    handle(value);
}
更安全:解析固定数据类型
// 对不可信输入关闭宽泛多态类型机制。
ObjectMapper mapper = new ObjectMapper();
OrderRequest value = mapper.readValue(
    untrustedBytes, OrderRequest.class
);
validate(value);

缺陷如何变得可达

API、队列、缓存或文件导入接收了用户可控字节。字节到达 ObjectInputStream.readObject() 后,JVM 会恢复进程中的可序列化类对象。gadget 链只是通过这些类行为的一种可能路径,并非每个数据流都有特殊载荷。Oracle 在 CVE-2015-4852 中记录了特定案例:针对所列版本通过 WebLogic T3 发起未认证网络攻击。这不表示所有 ObjectInputStream 用法都可远程触达。

若无法移除原生序列化

常见问题

ObjectInputFilter 能让 readObject() 安全吗?

窄范围白名单和读取前资源限制能降低风险,但它不是通用净化器。允许的类、其行为和过滤器是否实际生效都很重要;应用验证与授权仍不可少。尽可能避免对用户控制数据使用原生序列化。

一手来源

另请参阅 不安全反序列化:风险与修复 | flawopen.com Newtonsoft.Json TypeNameHandling:安全配置? PHP unserialize() 与不可信数据 Python pickle.load():不可信数据的安全风险 Ruby YAML.load 安全吗?Psych 版本与 safe_load .NET BinaryFormatter:风险与迁移