当前位置:首页 > 文章列表 > 文章 > java教程 > Java 序列化边界怎么收紧:白名单与替代格式

Java 序列化边界怎么收紧:白名单与替代格式

来源:17golang原创 2026-10-08 20:01:27 0浏览 收藏

Java 序列化边界要收紧,核心不是给 ObjectInputStream 再包一层异常,而是先限制“能读哪些类”,再限制“对象图能长多大”,最后把跨服务和不可信输入迁移到显式数据格式。只要输入不是完全受控的内部存储,就不应把原生反序列化当成通用消息协议。

要点速览
  • ObjectInputFilter 同时可以约束类名、数组长度、引用数、深度和输入字节数。
  • 白名单要覆盖业务 DTO 及其确实需要的 java.base 类型,不能用过宽的业务包通配。
  • 新接口优先使用带版本的 DTO 格式,迁移时保留可观测的旧格式读路径,并设置明确的下线条件。

本文依据 Java 官方序列化过滤文档和 ObjectInputStream API 说明边界;官方地址:https://docs.oracle.com/en/java/javase/25/core/java-serialization-filters.html。

先按输入来源划出三层边界

可信的本地快照、同一版本服务生成的内部缓存,可以暂时保留原生序列化,但读取入口仍应有资源上限。来自 HTTP、消息队列、文件上传、插件或跨团队服务的数据,应视为不可信;最稳妥的做法是拒绝原生反序列化,改用只承载业务字段的 DTO。不要把“加了过滤器”理解成“输入已经安全”,过滤器只是在对象恢复前增加一道允许/拒绝判断。

Java 序列化输入边界、过滤器与 DTO 领域边界的静态结构说明图
图1:序列化边界说明图,展示输入来源、过滤器和业务 DTO 的静态关系,不是运行截图。

建议把每个反序列化入口登记成一条策略:来源、允许的根对象、允许的包、最大深度、最大引用数、最大数组长度和最大字节数。这样异常日志里的 InvalidClassException 或过滤器拒绝原因,才能对应到具体业务入口,而不是只看到一条笼统的“反序列化失败”。

用白名单和资源上限保护 ObjectInputStream

简单场景可以使用 JVM 范围的模式过滤器;入口差异明显时,优先在每个流上设置更窄的过滤器。下面的模式只允许业务 DTO 和基础模块类型,同时限制对象图资源。!* 是拒绝其余类的关键边界,实际项目应把允许列表改成自己的稳定包名。

import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;

// 只给受控 DTO 和必要的基础类型开门,同时限制对象图规模。
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
    "maxdepth=12;maxrefs=2000;maxbytes=1048576;maxarray=10000;"
        + "com.example.order.dto.*;java.base/*;!*"
);

try (ObjectInputStream input = new ObjectInputStream(source)) {
    // 必须在第一次 readObject 前绑定过滤器,避免读取后再补策略。
    input.setObjectInputFilter(filter);
    OrderSnapshot snapshot = (OrderSnapshot) input.readObject();
    // 反序列化只恢复 DTO;业务校验仍在这里或更靠后的服务层完成。
    return snapshot;
} catch (java.io.InvalidClassException ex) {
    // 被拒绝的类或资源上限属于输入失败,记录入口标识后丢弃该流。
    throw new IllegalArgumentException("serialized input rejected", ex);
}

类名白名单和资源上限是两件事:前者阻止不需要的类型进入对象图,后者限制深度、引用数量、数组长度与字节消耗。即使业务对象本身在白名单内,也可能因为嵌套集合过深或输入过大而被拒绝。setObjectInputFilter 必须在读取对象前调用,而且过滤器不是业务字段校验器,日期范围、租户归属和状态转换仍要在 DTO 校验层处理。

用显式格式替代类路径驱动的跨服务协议

原生序列化把类名、字段演进和加载器关系带进载荷,跨服务升级时很容易变成隐式耦合。面向人工排查或开放接口,可采用 JSON;面向稳定 schema 和高吞吐二进制载荷,可采用 Protocol Buffers;需要二进制但保留较灵活结构时,可评估 CBOR。无论选哪一种,都让 DTO、版本字段和未知字段策略成为协议的一部分。

Java 原生对象图与显式 DTO 格式契约的静态关系说明图
图2:格式迁移结构图,对比类路径驱动的对象图与带版本 DTO 契约的静态边界,不是运行截图。

迁移不要一次性删除旧格式。可以先让新生产者写入显式格式,消费者保留旧格式只读并统计命中;当旧流量降到可接受范围,再把旧格式入口隔离到一次性迁移工具,最后删除服务运行时的 ObjectInputStream。双写期间要保证字段默认值、枚举未知值、时间精度和空值语义一致,避免“格式换了但业务含义悄悄变了”。

上线前用清单验收安全与兼容

  • 来源清单:每个读取入口是否标明可信来源、根对象和责任服务。
  • 过滤清单:是否有明确白名单;深度、引用、数组和字节上限是否来自样本而不是拍脑袋。
  • 异常清单:被拒绝的类、超限输入和格式损坏是否有脱敏日志、指标和限流策略。
  • 迁移清单:新旧格式的回放样本、版本兼容、回滚开关和旧入口下线时间是否写入发布记录。

最容易忽略的是把 java.base/* 当成万能信任。它只代表基础模块中的类型允许参与恢复,不代表业务对象可信,也不替代 DTO 字段校验。上线后应持续观察拒绝率、输入大小分布和旧格式命中率,按入口调整策略,而不是为了减少告警把白名单扩大到整个业务包。

相关问题

只配置 jdk.serialFilter 就够了吗?

它可以提供 JVM 范围的基线,但多个业务入口的允许类型不同,仍应补充流级或上下文级策略;配置也必须在部署参数中可追踪。

过滤器拒绝后能否继续读取同一个流?

不要把失败流交回正常业务路径。官方 API 将读取异常视为流状态不确定,应关闭并丢弃,再按入口记录原因。

换成 JSON 就不需要校验了吗?

不是。显式格式降低了类路径耦合,但仍要做大小限制、字段校验、版本兼容、权限和业务语义校验。

参考资料:https://docs.oracle.com/en/java/javase/25/core/java-serialization-filters.html;https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/io/ObjectInputStream.html;https://openjdk.org/jeps/290。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
封装 C 库句柄并明确创建、释放与线程约束封装 C 库句柄并明确创建、释放与线程约束
上一篇
封装 C 库句柄并明确创建、释放与线程约束
Go 指针为什么不能随意交给 C 长期保存,规则保护了什么
下一篇
Go 指针为什么不能随意交给 C 长期保存,规则保护了什么
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    379次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    450次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    460次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    402次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    231次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码