FastJson checkAutoType安全机制研究
字数 1974 2025-08-19 12:41:56

FastJson checkAutoType安全机制研究

1. 概述

FastJson在1.2.25及之后的版本中引入了checkAutoType安全机制,旨在防止autoType机制带来的安全隐患。本文详细分析checkAutoType的工作原理、触发条件以及可能的绕过方式。

2. checkAutoType机制基础

2.1 基本概念

  • autoType:FastJson的反序列化机制,通过@type字段指定要反序列化的类
  • checkAutoType:安全检测机制,用于验证@type指定的类是否安全

2.2 触发条件

checkAutoType机制并非在所有情况下都会被触发,以下情况不会触发:

  1. JSON字符串中未使用@type字段

    String jsonstr = "{\"s1\":\"1\"}";
    
  2. Class<T> clazz参数与@type指定的类相同

    // 不会触发checkAutoType
    JSON.parseObject("{\"@type\":\"AutoTypeTest.Test1\"}", AutoTypeTest.Test1.class);
    

3. checkAutoType工作机制

3.1 影响因素

checkAutoType的行为受以下两个主要因素影响:

  1. autoTypeSupport开关值(True/False)
  2. 使用parseObject(String text)parseObject(String text, Class<T> clazz)方法

组合情况如下表:

autoTypeSupport值 方法签名 情况编号
False parseObject(String text) 情况一
False parseObject(String text, Class clazz) 情况二
True parseObject(String text) 情况三
True parseObject(String text, Class clazz) 情况四

3.2 详细分析

情况一:autoTypeSupport=False,使用parseObject(String text)

  1. 程序首先检查黑名单(denyList)

    • 黑名单内容:
      bsh,com.mchange,com.sun.,java.lang.Thread,java.net.Socket,java.rmi,javax.xml,org.apache.bcel,org.apache.commons.beanutils,org.apache.commons.collections.Transformer,org.apache.commons.collections.functors,org.apache.commons.collections4.comparators,org.apache.commons.fileupload,org.apache.myfaces.context.servlet,org.apache.tomcat,org.apache.wicket.util,org.codehaus.groovy.runtime,org.hibernate,org.jboss,org.mozilla.javascript,org.python.core,org.springframework
      
    • 如果命中黑名单,抛出异常:"autoType is not support."
  2. 检查白名单(acceptList)

    • 默认情况下为空
    • 开发者可手动添加:
      ParserConfig.getGlobalInstance().addAccept("AutoTypeTest.Test1");
      
  3. 如果既不在黑名单也不在白名单,抛出异常

利用条件:@type字段值不在黑名单中且在白名单中

情况二:autoTypeSupport=False,使用parseObject(String text, Class clazz)

  1. 先检查白名单

    • 如果在白名单中,直接返回,跳过黑名单检查
  2. 检查黑名单

    • 如果命中黑名单,抛出异常
  3. 检查expectClass.isAssignableFrom(clazz)

    • 判断Class<T> clazz参数与@type指定的类是否有继承/实现关系
    • 如果没有,抛出异常:"type not match"

利用条件

  1. 不在黑名单且Class<T> clazz与@type指定的类有继承/实现关系
  2. @type字段值在白名单中

情况三:autoTypeSupport=True,使用parseObject(String text)

  1. 先检查白名单

    • 如果在白名单中,直接返回
  2. 检查黑名单

    • 如果命中黑名单,抛出异常
  3. 如果都不匹配,直接返回类

利用条件

  1. @type字段值不在黑名单中
  2. @type字段值在黑名单中但在白名单中

情况四:autoTypeSupport=True,使用parseObject(String text, Class clazz)

与情况二类似,但autoTypeSupport=True

4. 早期checkAutoType机制的缺陷

在FastJson 1.2.25及后续几个版本中,存在以下绕过方式:

4.1 L;格式绕过

当className以"L"开头并以";"结尾时:

  1. 程序会去除首尾字符
  2. 递归调用loadClass加载类

例如:

// 可以绕过黑名单检查
JSON.parseObject("{\"@type\":\"Lcom.sun.rowset.JdbcRowSetImpl;\"}");

绕过原理:

  1. 检查黑名单时,检查的是"Lcom.sun.rowset.JdbcRowSetImpl;",不在黑名单中
  2. 实际加载的是"com.sun.rowset.JdbcRowSetImpl"

5. 防御建议

  1. 保持FastJson版本更新
  2. 谨慎使用autoTypeSupport=true
  3. 合理配置白名单
  4. 避免使用不受信任的JSON数据进行反序列化

6. 总结

checkAutoType机制通过黑白名单和类型匹配来保证反序列化安全,但早期版本存在绕过方式。理解其工作原理有助于更好地配置和使用FastJson,避免安全风险。

FastJson checkAutoType安全机制研究 1. 概述 FastJson在1.2.25及之后的版本中引入了checkAutoType安全机制,旨在防止autoType机制带来的安全隐患。本文详细分析checkAutoType的工作原理、触发条件以及可能的绕过方式。 2. checkAutoType机制基础 2.1 基本概念 autoType :FastJson的反序列化机制,通过@type字段指定要反序列化的类 checkAutoType :安全检测机制,用于验证@type指定的类是否安全 2.2 触发条件 checkAutoType机制并非在所有情况下都会被触发,以下情况 不会 触发: JSON字符串中未使用@type字段 Class<T> clazz 参数与@type指定的类相同 3. checkAutoType工作机制 3.1 影响因素 checkAutoType的行为受以下两个主要因素影响: autoTypeSupport 开关值(True/False) 使用 parseObject(String text) 或 parseObject(String text, Class<T> clazz) 方法 组合情况如下表: | autoTypeSupport值 | 方法签名 | 情况编号 | |------------------|---------|---------| | False | parseObject(String text) | 情况一 | | False | parseObject(String text, Class clazz) | 情况二 | | True | parseObject(String text) | 情况三 | | True | parseObject(String text, Class clazz) | 情况四 | 3.2 详细分析 情况一:autoTypeSupport=False,使用parseObject(String text) 程序首先检查黑名单(denyList) 黑名单内容: 如果命中黑名单,抛出异常:"autoType is not support." 检查白名单(acceptList) 默认情况下为空 开发者可手动添加: 如果既不在黑名单也不在白名单,抛出异常 利用条件 :@type字段值不在黑名单中且在白名单中 情况二:autoTypeSupport=False,使用parseObject(String text, Class clazz) 先检查白名单 如果在白名单中,直接返回,跳过黑名单检查 检查黑名单 如果命中黑名单,抛出异常 检查 expectClass.isAssignableFrom(clazz) 判断 Class<T> clazz 参数与@type指定的类是否有继承/实现关系 如果没有,抛出异常:"type not match" 利用条件 : 不在黑名单且 Class<T> clazz 与@type指定的类有继承/实现关系 @type字段值在白名单中 情况三:autoTypeSupport=True,使用parseObject(String text) 先检查白名单 如果在白名单中,直接返回 检查黑名单 如果命中黑名单,抛出异常 如果都不匹配,直接返回类 利用条件 : @type字段值不在黑名单中 @type字段值在黑名单中但在白名单中 情况四:autoTypeSupport=True,使用parseObject(String text, Class clazz) 与情况二类似,但autoTypeSupport=True 4. 早期checkAutoType机制的缺陷 在FastJson 1.2.25及后续几个版本中,存在以下绕过方式: 4.1 L;格式绕过 当className以"L"开头并以";"结尾时: 程序会去除首尾字符 递归调用loadClass加载类 例如: 绕过原理: 检查黑名单时,检查的是"Lcom.sun.rowset.JdbcRowSetImpl;",不在黑名单中 实际加载的是"com.sun.rowset.JdbcRowSetImpl" 5. 防御建议 保持FastJson版本更新 谨慎使用autoTypeSupport=true 合理配置白名单 避免使用不受信任的JSON数据进行反序列化 6. 总结 checkAutoType机制通过黑白名单和类型匹配来保证反序列化安全,但早期版本存在绕过方式。理解其工作原理有助于更好地配置和使用FastJson,避免安全风险。