您现在的位置是:首页 > 编程 > 

FastJson checkAutoType安全机制研究

2025-07-29 15:11:35
FastJson checkAutoType安全机制研究 在FastJson1.2.25以及之后的版本中,fastjson为了防止autoType这一机制带来的安全隐患,增加了一层名为checkAutoType的检测机制。 在之后的版本中,随着checkAutoType安全机制被不断绕过,fastjson也进行了一系列例如黑名单防逆向分析、扩展黑名单列表等加固。但是 checkAutoType的

FastJson checkAutoType安全机制研究

在FastJson1.2.25以及之后的版本中,fastjson为了防止autoType这一机制带来的安全隐患,增加了一层名为checkAutoType的检测机制。

在之后的版本中,随着checkAutoType安全机制被不断绕过,fastjson也进行了一系列例如黑名单防逆向分析、扩展黑名单列表等加固。但是 checkAutoType的原理未曾有过大的变化,因此本文将以fastjson 1.2.25版本为例,介绍一下checkAutoType安全机制的原理

在调试分析fastjson的checkAutoType安全机制之前,发现网上很多fastjson漏洞的分析文章中曾经提到过一个名为autoTypeSupport的开关,且在1.2.25以及之后的版本中默认关闭。在动手调试之前,我曾一度以为autoTypeSupport开关关闭与否直接决定了fastjson是完全摒弃或是使用autotype功能的。但是实际调试中发现,这个开关仅仅是checkAutoType安全机制中的一个选项,这个开关的关闭与否并不直接作用于fastjson是否使用autoType机制,下文案例中可以看出这个问题。

fastjson在1.2.25以及之后的版本中引入了一个checkAutoType安全机制,位于com/alibaba/fastjson/parser/ParserConfig.java文件。但并不是所有情况下fastjson都会加载这个机制进行安全监测,让我们下面来看看究竟什么情况下这个安全机制会被触发

通过调试fastjson 1.2.25代码发现,如果想触发checkAutoType安全机制则需要执行到中下图红框处位置: com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java

下面我们首先看下在什么情况下不会使用checkAutoType安全机制

不使用checkAutoType

一、json字符串中未使用@type字段

代码语言:javascript代码运行次数:0运行复制
String jstr = "{\"s1\":\"1\"}";

显然,这里连@type字段都没有,这就是个最普通的json字符串转换为java对象的方法,因此根本进入不了上文中触发userType = (typeame, expectClass);的位置

二、Class\<T> clazz与@type相同

其次我们再看另一种情况

这里@type指定的类与parseObject(String text, Class\<T> clazz)中Class\<T> clazz)指定的类是一样的,都是AutoTypeTest.Test1

在上图中,由@type指定的typeame变量与parseObject(String text, Class\<T> clazz)中Class\<T> clazz指定的变量值完全一样,因此程序在这个if分支中,在这个上图红框中的if分支,程序不是break就是continue,无论如何也不会执行到上图552行的checkAutoType安全机制中

由上文两个例子可见,在1.2.25以及之后的版本中并不是所有的情况都需要经过checkAutoType这一关卡的。

我们接下来看看如何触发checkAutoType安全机制,以及checkAutoType安全机制的原理

使用checkAutoType

通过我的分析,checkAutoType安全机制中也是针对不同情况不同处理的,例如文章开头所说的autoTypeSupport开关等一些元素,这些元素总和起来一起觉得checkAutoType安全机制是如何过滤以及处理传入的等待反序列化的json字符串

总得来说,有如下几个元素共同作用影响checkAutoType选择哪种方式处理输入

1、autoTypeSupport开关值(True/False)

2、使用parseObject(String text, Class\<T> clazz)或是parseObject(String text)(这里Class\<T> clazz参数为应与@type字段不一样的值,否则不会触发checkAutoType)

根据这两种条件,我们可以列出如下四种情况的表格:

一、autoTypeSupport值为False、使用parseObject(String text)

由于autoTypeSupport为False,程序进入如下分支

程序首先遍历denyList这一黑名单并判断classame与黑名单是否匹配

这里需要说明一下classame变量是从哪来的,classame变量是由typeame简单变换而来的,详见下图代码

而typeame即为@type字段值,接下来看下黑名单中的元素:

代码语言:javascript代码运行次数:0运行复制
denyList =
"bsh,,com.sun.,java.lang.Thread,java.Socket,java.rmi,javax.xml,org.apache.bcel,org.apachem.beanutils,org.Transformer,org.functors,org.,org.apachem.fileupload,org.servlet,org.,org.apache.wicket.util,groovy.runtime,org.hibernate,org.jboss,javascript,org.,org.springframework"

如果classame命中黑名单,程序抛出异常

代码语言:javascript代码运行次数:0运行复制
autoType is not support.

程序结束

黑名单过滤完成后,程序还会将classame与白名单匹配一下

这里的acceptList即为白名单,默认情况下为空

开发者可以自行向acceptList中增加元素。方法见下图48行处,向白名单中增加了一个AutoTypeTest.Test1类

当classame与白名单相匹,程序会将这个类返回并将传入的json字符串反序列化为这个类的对象

然而程序执行完黑名单与白名单校验后,即没有匹配到黑名单,也没有匹配到白名单的话,程序最终会执行到下图代码段

程序抛出异常结束

由于在1.2.25以及之后的版本中,autoTypeSupport值默认False。所以在这种情况下,即使攻击者的payload绕过了黑名单,但如果你的payload不在白名单上,也是不能成功利用的。值得注意的是,白名单默认是空的

在这种情况下,payload想执行成功,有一种可能性:

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

二、autoTypeSupport值为False、使用parseObject(String text, Class\<T> clazz)

注意上图,这里parseObject中的Class\<T> clazz参数是AutoTypeTest.,而@type中的是AutoTypeTest.Test1,二者不是一个类。如果是一个类,根据上文checkAutoType触发条件分析,根本不会触发checkAutoType

程序会执行到如下if分支中

值得注意的是,这个分支中是先匹配白名单,后匹配黑名单,如果@type字段指定的类在白名单中,则直接返回,不需要再经过黑名单过滤了。这一点很有意思,如果开发者因为开发失误,将存在利用的类加到了白名单里,攻击者是可以直接利用的

回归正文,由于上图这里我们没有向白名单中增加AutoTypeTest.类,程序会接下来检查传入的类是否在黑名单中

如果匹配到黑名单,则直接抛出错误

如果这里既没有匹配到白名单直接返回,也没有匹配到黑名单抛出错误终止,程序则继续向下执行

继续执行到的这个分支与情况一中的完全一致,又匹配了一遍黑名单与白名单。显而易见,这里既不会匹配到白名单,也不会匹配到黑名单

最后程序执行到下图这里

由于我们使用的是parseObject(String text, Class\<T> clazz) 这种方式,上图代码中872行处的expectClass即为Class\<T> clazz传入的AutoTypeTest.类,而clazz变量为@type字段指定的AutoTypeTest.类.程序通过

expectClass.isAssignableFrom(clazz)

判断@type字段指定的clazz变量与Class\<T> clazz传入的expectClass是否

是判断 Class\<T> clazz传入的expectClass对象表示的类或接口是否与指定的@type字段指定的clazz变量参数表示的类或接口相同,或者是其超类或父接口。这里AutoTypeTest.类与AutoTypeTest.类所表示的类与接口不同,也不是超类或父类关系。因此程序抛出

Exception in thread "main" com.alibaba.fastjson.JSOException: type not match.AutoTypeTest.Test1 -> AutoTypeTest.Test

异常

在1.2.25以及之后的版本中autoTypeSupport值默认为False。在这种情况下,程序会先匹配白名单,后匹配黑名单。如果@type字段指定的类在白名单中,则程序是会跳过黑名单校验的,例如下图:

即使com.sun.rowset.JdbcRowSetImpl在黑名单中,但在开发的时候,由于开发安全意识不强或开发疏忽等原因,将com.sun.rowset.JdbcRowSetImpl加入了白名单,此时是可以绕过黑名单直接执行利用的

在这种情况下,payload想执行成功,有两种可能性:

1、没有命中黑名单且Class\<T> clazz表示的类或接口是否与指定的@type字段值表示的类或接口相同,或者是其超类或父接口。

2、@type字段值在白名单中

三、autoTypeSupport值为True、使用parseObject(String text)

这里首先进入了与autoTypeSupport值为False、使用parseObject(String text, Class\<T> clazz)类型相同的分支

先匹配白名单,后匹配黑名单。如果@type字段指定的类在白名单中,则直接返回,不再进行黑名单校验。在白名单未匹配成功后,使用黑名单进行匹配,若匹配到黑名单,直接抛出异常。如果黑白名单都未匹配成功,程序继续向下执行

程序将@type字段指定的类返回

这种情况下要是payload想成功利用有两种办法:

1、@type字段值只需要不在黑名单中即可成功利用

2、@type字段值在黑名单中,但是开发的时候在白名单中加入了这个类,payload依然可以成功利用

四、autoTypeSupport值为True、使用parseObject(String text, Class\<T> clazz)

与上文二、三节相同相同,先进入了这个分支

这里不再复述了

在没有匹配到黑白名单后,程序执行到了下图这里

由于这里clazz与expectClass所表示的类与接口不同,也不是超类或父类关系。因此程序抛出

Exception in thread "main" com.alibaba.fastjson.JSOException: type not match.AutoTypeTest.Test1 -> AutoTypeTest.Test

异常

在这种情况下,payload想执行成功,有两种可能性:

1、没有命中黑名单且Class\<T> clazz表示的类或接口是否与指定的@type字段值表示的类或接口相同,或者是其超类或父接口。

2、@type字段值在白名单中

早期checkAutoType安全机制缺陷

在fastjson 1.2.25版本引入的checkAutoType以及后续的几个版本中存在着一定的缺陷

如上文所分析,程序通常先经过黑名单与白名单的校验后,将满足条件的clazz进行返回

我们来看下这个clazz是如何获得的

可见clazz是通过@type字段值获得而来

解析来看下TypeUtils.loadClass是如何实现的

注意上图的1089行

当传入的classame变量以”L”开头,并以”;”结尾,进入上图分支 程序将会把开头的”L”与结尾的”;”去掉,并递归调用loadClass加载这个类 因此可以下图这样构造来进行绕过

loadClass会将”L”与”;”去除后组成newClassame并返回

这一操作在匹配黑白名单之后,Lcom.sun.rowset.JdbcRowSetImpl;恰好可以绕过黑名单中的限制。后续checkAutoType检测机制进行了一系列的安全加固,大体上都是黑名单防逆向分析、扩展黑名单列表等,但checkAutoType检测机制没有太大的改变。受篇幅影响,这里就不再详细分析了

本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2025-01-09,如有侵权请联系 cloudcommunity@tencent 删除安全fastjson变量程序接口

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1187219.html

相关标签:无
上传时间: 2025-07-22 13:46:31
留言与评论(共有 17 条评论)
本站网友 葡萄糖酸锌
16分钟前 发表
javax.xml
本站网友 南京租房中介
5分钟前 发表
我曾一度以为autoTypeSupport开关关闭与否直接决定了fastjson是完全摒弃或是使用autotype功能的
本站网友 伊人综在合线
10分钟前 发表
groovy.runtime
本站网友 太阳神
2分钟前 发表
这一点很有意思
本站网友 北京寄宿学校
6分钟前 发表
在之后的版本中
本站网友 儿童卧室装修效果图
27分钟前 发表
在这种情况下
本站网友 胀气
5分钟前 发表
payload想执行成功
本站网友 摸虾网
16分钟前 发表
Class\<T> clazz)或是parseObject(String text)(这里Class\<T> clazz参数为应与@type字段不一样的值
本站网友 昆山中荣
1秒前 发表
根本不会触发checkAutoType程序会执行到如下if分支中值得注意的是
本站网友 上海星河湾
27分钟前 发表
也是不能成功利用的
本站网友 农行一卡通
2分钟前 发表
将满足条件的clazz进行返回我们来看下这个clazz是如何获得的可见clazz是通过@type字段值获得而来解析来看下TypeUtils.loadClass是如何实现的注意上图的1089行当传入的classame变量以”L”开头
本站网友 长兴二手房
22分钟前 发表
classame变量是由typeame简单变换而来的
本站网友 金库ktv
24分钟前 发表
有一种可能性:@type字段值在不在黑名单中且在白名单中二
本站网友 七星彩彩票论坛
29分钟前 发表
Class\<T> clazz)中Class\<T> clazz)指定的类是一样的
本站网友 绫小路清隆
9分钟前 发表
fastjson为了防止autoType这一机制带来的安全隐患
本站网友 大唐西市酒店
30分钟前 发表
程序还会将classame与白名单匹配一下这里的acceptList即为白名单