如何理解Java序列化过滤机制并防止反序列化漏洞

来源:苹果APP网作者:缓存小熊猫头衔:程序员
导读:本期聚焦于小伙伴创作的《如何理解Java序列化过滤机制并防止反序列化漏洞》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何理解Java序列化过滤机制并防止反序列化漏洞》有用,将其分享出去将是对创作者最好的鼓励。

Java序列化机制允许将对象转换为字节流进行存储或传输,反序列化则是将字节流恢复为对象的过程。如果反序列化时未对输入数据做校验,攻击者可以构造包含恶意类的序列化数据,触发任意代码执行,这就是反序列化漏洞的成因。序列化过滤机制就是用来限制反序列化过程中允许加载的类,从而防御这类攻击。

如何理解Java序列化过滤机制并防止反序列化漏洞

Java序列化过滤机制的核心原理

Java从8u121版本开始引入ObjectInputFilter接口,作为序列化过滤的核心组件。该接口会在反序列化过程中对每个要恢复的类进行检查,根据预设的规则决定是否允许该类被反序列化。过滤规则可以基于类的名称、类的父类、类的接口等多个维度进行配置。

过滤器的检查结果分为三种状态:

  • ALLOWED:允许该类被反序列化
  • REJECTED:拒绝该类被反序列化,会直接抛出InvalidClassException
  • UNDECIDED:未做明确判断,交由下一个过滤器或者默认规则处理

内置序列化过滤器的使用方式

全局过滤器配置

可以通过JVM参数设置全局的序列化过滤器,对所有反序列化操作生效。配置格式为指定允许或者拒绝的类模式,多个模式之间用分号分隔。

例如只允许反序列化java.util包下的类,拒绝org.apache包下的类,可以添加JVM参数:

-Djdk.serialFilter=java.util.*;!org.apache.*

其中!前缀表示拒绝匹配的类,通配符*匹配任意字符。

局部过滤器设置

也可以在单个ObjectInputStream实例上设置过滤器,只对当前流的反序列化操作生效。示例代码如下:

import java.io.*;
import java.util.ArrayList;

public class SerialFilterDemo {
    public static void main(String[] args) throws Exception {
        // 构造测试序列化数据,这里简化为模拟反序列化过程
        byte[] data = serializeData();
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
        // 设置局部过滤器,只允许ArrayList类被反序列化
        ois.setObjectInputFilter(filterInfo -> {
            String className = filterInfo.serialClass() == null ? null : filterInfo.serialClass().getName();
            if (className != null && className.equals("java.util.ArrayList")) {
                return ObjectInputFilter.Status.ALLOWED;
            }
            return ObjectInputFilter.Status.REJECTED;
        });
        // 执行反序列化
        Object obj = ois.readObject();
        System.out.println("反序列化结果:" + obj);
    }

    private static byte[] serializeData() throws Exception {
        ArrayList<String> list = new ArrayList<>();
        list.add("test");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(list);
        return bos.toByteArray();
    }
}

自定义过滤器的实现方案

如果需要更复杂的过滤逻辑,可以实现ObjectInputFilter接口自定义过滤器。比如需要同时校验类的包名和类的注解信息,可以编写如下自定义过滤器:

import java.io.ObjectInputFilter;

public class CustomSerialFilter implements ObjectInputFilter {
    // 允许反序列化的包名白名单
    private static final String[] ALLOW_PACKAGES = {"java.lang", "java.util", "com.example.dto"};

    @Override
    public Status checkInput(FilterInfo filterInfo) {
        Class<?> serialClass = filterInfo.serialClass();
        // 如果当前处理的是类信息
        if (serialClass != null) {
            String className = serialClass.getName();
            // 检查是否在白名单包下
            for (String pkg : ALLOW_PACKAGES) {
                if (className.startsWith(pkg)) {
                    return Status.ALLOWED;
                }
            }
            // 不在白名单的类直接拒绝
            return Status.REJECTED;
        }
        // 非类信息的检查返回未决定,交由其他规则处理
        return Status.UNDECIDED;
    }
}

使用自定义过滤器时,既可以设置为全局过滤器,也可以设置为局部过滤器:

// 设置为局部过滤器
ObjectInputStream ois = new ObjectInputStream(inputStream);
ois.setObjectInputFilter(new CustomSerialFilter());

防止反序列化漏洞的安全实践

最小权限原则配置过滤规则

尽量使用白名单模式配置过滤规则,只允许业务必需的类被反序列化,不要使用黑名单模式。黑名单很难覆盖所有可能的恶意类,比如攻击者可以构造新的利用链绕过黑名单限制,而白名单只要严格控制允许的范围,就能从根本上避免未知类的加载。

避免反序列化不可信数据

如果业务场景允许,尽量不要反序列化来自不可信来源的数据。如果必须反序列化外部输入,一定要先经过序列化过滤校验,同时不要将反序列化接口直接暴露给外部用户,避免攻击者直接构造恶意数据传入。

及时更新JDK版本

Java官方会持续修复序列化相关的安全漏洞,及时更新到最新的稳定JDK版本,可以获得官方提供的安全补丁和更完善的过滤机制支持。同时关注官方发布的安全公告,针对已知的序列化漏洞及时做对应的防护配置。

结合其他安全措施

序列化过滤只是防御反序列化漏洞的一层措施,还可以结合数据签名、加密传输等方式,确保序列化数据在传输过程中没有被篡改,进一步降低安全风险。如果反序列化的数据需要持久化,存储时也要做好权限控制,避免数据被恶意替换。

注意:序列化过滤机制不能完全替代其他安全措施,需要结合整体安全架构设计,才能最大程度降低反序列化漏洞带来的风险。

Java序列化反序列化漏洞序列化过滤ObjectInputFilter安全实践修改时间:2026-07-04 12:00:27

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。