反序列化漏洞的末日?JEP290机制研究
字数 1517 2025-08-29 08:31:47

JEP290机制详解:Java反序列化漏洞的防护新标准

0x00 背景介绍

JEP290是Oracle在2016年提出的Java增强提案,最初是为Java 9设计的新特性,但随后被向下移植到JDK 6、7、8版本中。该机制的主要目的是提供一套标准化的反序列化防护方案,有效缓解Java反序列化漏洞带来的安全风险。

版本支持情况

  • JDK 8u121
  • JDK 7u131
  • JDK 6u141

0x01 JEP290核心机制

JEP290主要实现了以下安全机制:

  1. 类过滤机制:提供黑白名单方式限制可反序列化的类
  2. 复杂度限制:控制反序列化的深度和复杂度
  3. RMI验证:为RMI远程调用对象提供类验证机制
  4. 可配置过滤:支持通过properties文件定义过滤器

ObjectInputFilter接口

JEP290的核心是ObjectInputFilter接口,开发者可以通过ObjectInputStream.setInternalObjectInputFilter()方法设置过滤器。在反序列化过程中,底层会根据过滤器规则进行判断,返回三种状态:

  • Status.ACCEPT:允许反序列化
  • Status.REJECT:拒绝反序列化
  • Status.UNDECIDED:未决定,由后续过滤器决定

0x02 配置方式

JEP290提供了两种配置过滤器的方式:

  1. 系统属性配置

    System.setProperty("jdk.serialFilter", "规则表达式");
    
  2. 配置文件
    修改conf/security/java.properties文件

0x03 RMI过滤机制详解

RMI(远程方法调用)是Java反序列化漏洞的高发区域。JEP290为RMI引入了专门的过滤机制:

过滤流程

  1. 在导出远程对象前,先执行过滤器逻辑
  2. 反序列化时检查每个类是否符合过滤规则
  3. 对于不符合规则的类直接抛出异常

核心过滤逻辑

RegistryImpl.registryFilter方法中,RMI对远程对象的检查条件如下:

return String.class != var2 && 
       !Number.class.isAssignableFrom(var2) && 
       !Remote.class.isAssignableFrom(var2) && 
       !Proxy.class.isAssignableFrom(var2) && 
       !UnicastRef.class.isAssignableFrom(var2) && 
       !RMIClientSocketFactory.class.isAssignableFrom(var2) && 
       !RMIServerSocketFactory.class.isAssignableFrom(var2) && 
       !ActivationID.class.isAssignableFrom(var2) && 
       !UID.class.isAssignableFrom(var2) 
       ? Status.REJECTED : Status.ALLOWED;

这个规则明确禁止了AnnotationInvocationHandler等常用于攻击的类。

0x04 技术实现细节

反序列化检查流程

  1. ObjectInputStream.readObject()开始反序列化
  2. 调用readObject0()方法
  3. 进入readOrdinaryObject()readClassDesc()readProxyDesc()
  4. 获取接口并逐个调用filterCheck方法检查
  5. 最后对对象本身进行检查

过滤器检查方法

private Status filterCheck(Class<?> clazz, int arrayLength) {
    if (serialFilter != null) {
        return serialFilter.checkInput(new FilterValues(clazz, arrayLength, ...));
    }
    return Status.UNDECIDED;
}

0x05 安全影响分析

  1. 防护效果

    • 有效拦截了已知的恶意反序列化链
    • 提供了标准化的防护方案,减少了自定义过滤器的实现风险
  2. 局限性

    • 黑名单机制仍可能遗漏某些库或新出现的gadgets
    • 开发者配置不当仍可能导致防护失效
    • 不覆盖所有Java序列化场景
  3. 绕过可能性

    • 寻找不在黑名单中的新gadget链
    • 利用白名单中的类构造攻击链
    • 针对特定应用的定制化绕过

0x06 最佳实践建议

  1. 及时更新JDK:确保使用支持JEP290的JDK版本
  2. 配置严格规则:尽可能使用白名单而非黑名单
  3. 自定义过滤器:根据应用特点扩展过滤规则
  4. 监控与审计:记录被拦截的序列化尝试
  5. 深度防御:JEP290应作为安全策略的一部分,而非唯一防护措施

0x07 总结

JEP290机制的引入标志着Java官方对反序列化安全问题的高度重视,为开发者提供了标准化的防护方案。虽然不能完全消除反序列化漏洞的风险,但显著提高了攻击门槛,迫使攻击者寻找更复杂、更受限的攻击路径。开发者应当充分了解这一机制,合理配置并配合其他安全措施,构建纵深防御体系。

JEP290机制详解:Java反序列化漏洞的防护新标准 0x00 背景介绍 JEP290是Oracle在2016年提出的Java增强提案,最初是为Java 9设计的新特性,但随后被向下移植到JDK 6、7、8版本中。该机制的主要目的是提供一套标准化的反序列化防护方案,有效缓解Java反序列化漏洞带来的安全风险。 版本支持情况 : JDK 8u121 JDK 7u131 JDK 6u141 0x01 JEP290核心机制 JEP290主要实现了以下安全机制: 类过滤机制 :提供黑白名单方式限制可反序列化的类 复杂度限制 :控制反序列化的深度和复杂度 RMI验证 :为RMI远程调用对象提供类验证机制 可配置过滤 :支持通过properties文件定义过滤器 ObjectInputFilter接口 JEP290的核心是 ObjectInputFilter 接口,开发者可以通过 ObjectInputStream.setInternalObjectInputFilter() 方法设置过滤器。在反序列化过程中,底层会根据过滤器规则进行判断,返回三种状态: Status.ACCEPT :允许反序列化 Status.REJECT :拒绝反序列化 Status.UNDECIDED :未决定,由后续过滤器决定 0x02 配置方式 JEP290提供了两种配置过滤器的方式: 系统属性配置 : 配置文件 : 修改 conf/security/java.properties 文件 0x03 RMI过滤机制详解 RMI(远程方法调用)是Java反序列化漏洞的高发区域。JEP290为RMI引入了专门的过滤机制: 过滤流程 在导出远程对象前,先执行过滤器逻辑 反序列化时检查每个类是否符合过滤规则 对于不符合规则的类直接抛出异常 核心过滤逻辑 在 RegistryImpl.registryFilter 方法中,RMI对远程对象的检查条件如下: 这个规则明确禁止了 AnnotationInvocationHandler 等常用于攻击的类。 0x04 技术实现细节 反序列化检查流程 ObjectInputStream.readObject() 开始反序列化 调用 readObject0() 方法 进入 readOrdinaryObject() → readClassDesc() → readProxyDesc() 获取接口并逐个调用 filterCheck 方法检查 最后对对象本身进行检查 过滤器检查方法 0x05 安全影响分析 防护效果 : 有效拦截了已知的恶意反序列化链 提供了标准化的防护方案,减少了自定义过滤器的实现风险 局限性 : 黑名单机制仍可能遗漏某些库或新出现的gadgets 开发者配置不当仍可能导致防护失效 不覆盖所有Java序列化场景 绕过可能性 : 寻找不在黑名单中的新gadget链 利用白名单中的类构造攻击链 针对特定应用的定制化绕过 0x06 最佳实践建议 及时更新JDK :确保使用支持JEP290的JDK版本 配置严格规则 :尽可能使用白名单而非黑名单 自定义过滤器 :根据应用特点扩展过滤规则 监控与审计 :记录被拦截的序列化尝试 深度防御 :JEP290应作为安全策略的一部分,而非唯一防护措施 0x07 总结 JEP290机制的引入标志着Java官方对反序列化安全问题的高度重视,为开发者提供了标准化的防护方案。虽然不能完全消除反序列化漏洞的风险,但显著提高了攻击门槛,迫使攻击者寻找更复杂、更受限的攻击路径。开发者应当充分了解这一机制,合理配置并配合其他安全措施,构建纵深防御体系。