Java ObjectInputFilter 怎么拦截反序列化:按类名、数组长度与深度做白名单验收
老系统把订单快照存成 Java 序列化字节,升级接口后,最麻烦的不是“能不能读出来”,而是输入里混进了不属于这个模块的类,或者数组和对象引用规模远超正常订单。把数据读进 ObjectInputStream 之前加一层 ObjectInputFilter,可以先按类名和资源上限做一次拦截。
- 白名单过滤优先允许业务 DTO 和必要的
java.base类型,其他类保持拒绝或未决,别只维护一份越来越长的黑名单。 FilterInfo能提供当前类、数组长度、对象图深度、引用数和输入字节数,类名检查与资源限制要同时做。createFilter的模式用分号分隔,maxarray、maxdepth等限制和类模式共同决定结果,顺序写错会让验收失真。- 过滤器是防御层,不等于可以放心读取不可信序列化数据;新接口优先选 JSON、协议缓冲等明确格式。
先画清楚:输入要过哪几道门
把一次订单快照读取拆成三步更容易验收:先判断当前类是否属于允许集合,再判断数组和对象图是否超过正常规模,最后才让 ObjectInputStream 继续读取。过滤器检查的是反序列化过程中的对象信息,不会提前替你检查每个字段的业务含义。

这里要特别注意边界:Oracle 文档明确提醒,不可信数据的反序列化本身就有风险。过滤器的价值是缩小可接受的类集合并限制对象图复杂度,不能把历史序列化格式变成一种天然安全的交换协议。
最小可用写法:只允许订单快照和基础类型
假设业务只保存 OrderSnapshot、OrderLine 和少量集合数据。先用模式过滤器限制包范围,再把输入流绑定到这个过滤器:
import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
Object readSnapshot(Path file) throws Exception {
var pattern = "com.example.order.**;java.base/*;maxarray=200;maxdepth=12;!*";
var filter = ObjectInputFilter.Config.createFilter(pattern);
try (var input = Files.newInputStream(file);
var objects = new ObjectInputStream(input)) {
objects.setObjectInputFilter(filter);
return objects.readObject();
}
}
java.base/* 让基础模块中的必要类型参与匹配,最后的 !* 把没有被前面模式覆盖的类拒绝掉。数组上限和深度上限不是装饰项:订单行数量异常、嵌套集合过深时,过滤器应当在读取过程中返回拒绝状态。
自定义检查:把“允许什么”和“最多多少”分开
模式字符串适合固定规则;如果还要记录拒绝原因,可以实现一个小型过滤器。返回 UNDECIDED 表示本过滤器暂不做决定,返回 ALLOWED 或 REJECTED 才是明确结论:
ObjectInputFilter orderFilter = info -> {
Class> type = info.serialClass();
if (info.arrayLength() > 200 || info.depth() > 12) {
return ObjectInputFilter.Status.REJECTED;
}
if (type == null) {
return ObjectInputFilter.Status.UNDECIDED;
}
if (type.getName().startsWith("com.example.order.")) {
return ObjectInputFilter.Status.ALLOWED;
}
if (type.getModule().getName().equals("java.base")) {
return ObjectInputFilter.Status.ALLOWED;
}
return ObjectInputFilter.Status.REJECTED;
};
数组检查不能只在 serialClass() 非空时执行,因为数组长度是过滤器单独提供的指标。对象图深度也应结合真实订单样本测出上限,直接照抄一个很小的数字,可能把合法的嵌套 DTO 一起挡掉。
威胁路径:黑名单为什么越补越被动
黑名单的思路是“遇到一个危险类就加一条拒绝规则”,但业务依赖、库版本和类加载范围一变,遗漏就会重新出现。白名单的边界更清楚:订单读取器只需要少数 DTO 和基础类型,未声明的类不应该因为“暂时没发现问题”而自动进入。
如果多个模块各自设置流级过滤器,还要审查 JVM 级过滤器和过滤器工厂的合并关系。Oracle 的过滤文档强调,组合过滤器遇到任一明确拒绝时应拒绝;不能在局部过滤器里简单返回新规则,反而绕开全局安全边界。

用四组样本做验收,不看一次成功就收工
| 样本 | 预期结果 | 核对点 |
|---|---|---|
| 正常 OrderSnapshot | 允许读取 | 业务包名、数组长度、深度都在范围内 |
| 未登记的业务类 | 拒绝读取 | 日志能定位到 serialClass |
| 超长 OrderLine 数组 | 拒绝读取 | arrayLength 超过 maxarray |
| 多层嵌套快照 | 拒绝读取 | depth 超过 maxdepth,业务侧保留失败记录 |
每组样本都要记录过滤器配置、Java 版本、结果状态和失败原因。不要只断言“抛了异常”,还要确认是输入类不允许、数组超限还是深度超限,否则规则改动后很难知道到底放宽了哪一道门。
上线前的安全清单
- 能改协议就停止新增 Java 原生序列化入口,迁移到字段和版本都更明确的格式。
- 必须兼容旧数据时,先盘点每个读取点的 DTO 白名单,再设置数组、深度、引用数和字节数上限。
- 把过滤器拒绝日志接入告警,但不要把完整输入内容和敏感订单字段写进日志。
- 升级 JDK、引入新 DTO 或新增集合字段后,重新跑四组边界样本。
相关问题
ObjectInputFilter 能让不可信序列化数据变安全吗?
不能。它是类和资源边界的防御控制,不能替代避免读取不可信数据、认证来源和迁移到更明确数据格式等措施。
ALLOWED 和 UNDECIDED 有什么区别?
ALLOWED 是当前过滤器明确放行,UNDECIDED 是当前过滤器不表态,组合过滤器或后续规则仍可能给出拒绝。
只设置 maxdepth 够不够?
通常不够。对象图深度、引用数、数组长度和输入字节数限制关注的是不同资源维度,应根据正常样本组合设置并用边界数据验证。
过滤器应该设置在全局还是单个流上?
全局规则适合统一底线,单个流适合更严格的业务白名单。多层规则并存时要确认组合逻辑没有绕开全局过滤器。
把过滤器当成协议边界来维护
ObjectInputFilter 最有用的地方,不是帮旧序列化代码“加一行安全配置”,而是把可读类集合、对象图规模和验收样本都明确下来。先收紧输入边界,再逐步迁移掉不必要的原生序列化,才是更稳妥的长期方案。可继续参考 OpenJDK JEP 290、Oracle ObjectInputFilter API 和 Oracle Serialization Filtering 指南。
PHP 8.5 clone() with 怎么更新 readonly DTO:浅拷贝、嵌套对象与回滚边界
- 上一篇
- PHP 8.5 clone() with 怎么更新 readonly DTO:浅拷贝、嵌套对象与回滚边界
- 下一篇
- Java ObjectInputFilter 拒绝后怎么定位:serialClass、depth 与 arrayLength 测试清单
-
- 文章 · java教程 | 4小时前 | 反序列化 · Java教程 · 安全编程 · Java IO · java Java安全 ObjectInputFilter 反序列化过滤 Serialization Filter
- Java ObjectInputFilter 拒绝后怎么定位:serialClass、depth 与 arrayLength 测试清单
- 257浏览 收藏
-
- 文章 · java教程 | 5小时前 | Java · jdk · 字节码 · Java 25 Class-File API java.lang.classfile 方法描述符
- Java 25 Class-File API 怎么读取方法描述符:元素遍历、懒解析与版本门禁
- 143浏览 收藏
-
- 文章 · java教程 | 7小时前 | Java教程 · Java 24 · 字节码 · Class-File API · JVM工具 · 字节码 Java 24 Class-File API ClassModel ASM替代 java.lang.classfile
- Java class 文件 major version 怎么查:ClassFileVersion 与高版本拒绝的排查实验
- 352浏览 收藏
-
- 文章 · java教程 | 8小时前 | 并发编程 · Java教程 · 虚拟线程 · threadlocal 请求上下文 Java 25 StructuredTaskScope ScopedValue
- Java 25 ScopedValue 怎么替代 ThreadLocal:请求上下文的边界与并发验收
- 391浏览 收藏
-
- 文章 · java教程 | 5天前 |
- Java 文件上传如何挡住路径穿越:Path.normalize、真实路径与原子落盘
- 296浏览 收藏
-
- 文章 · java教程 | 1星期前 | Stream · Java教程 · 性能边界 · mapMulti · flatMap · Java mapMulti Stream flatMap Java Stream 条件展开 Java 16
- Java Stream mapMulti 怎么替代 flatMap:条件展开、空结果与分配边界
- 250浏览 收藏
-
- 文章 · java教程 | 1星期前 | Java · 类型安全 · 面向对象 · 支付系统 · 代码设计 · java 支付渠道 sealed interface 类型建模 enum switch
- Java sealed interface 做支付渠道路由:和 enum + switch 怎么选
- 242浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ljg-skills
- ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
- 4912次使用
-
- MELO音乐
- MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
- 4487次使用
-
- UniScribe
- UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
- 4432次使用
-
- 剧云
- 剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
- 4671次使用
-
- 万象有声
- 万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
- 4630次使用
-
- Go语言对JSON数据进行序列化和反序列化
- 2023-01-07 487浏览
-
- Golang中Json的序列化和反序列化的使用
- 2022-12-29 313浏览
-
- Go语言基础Json序列化反序列化及文件读写示例详解
- 2022-12-30 196浏览
-
- golang:json 反序列化的[]和nil操作
- 2023-02-16 306浏览
-
- golang的序列化与反序列化的几种方式
- 2023-01-07 393浏览

