v1.2.70-FastJson的AutoType机制研究

2024-06-05 11:04

本文主要是介绍v1.2.70-FastJson的AutoType机制研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

v1.2.70-FastJson的AutoType机制研究

最近在对接Alexa亚马逊语音技能,Smart Home Skill Apis时,有一个配置的JSON字符串是这样的:

     { "capabilityResources": {"friendlyNames": [{"@type": "asset","value": {"assetId": "Alexa.Setting.Opening"}}]}}

在开发配置,只当是一个普通的字符串;直到单测开始,在解析这行字符串成JSONObject对象的时候报错,同时也抛出了一个异常:

Exception in thread "main" com.alibaba.fastjson.JSONException: autoType is not support. asset

fastjson版本是:

        <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.70</version></dependency>

autoType is not support,是什么含义,为什么fastjson独对这个字符串进行了check设置了ParserConfig.checkAutoType方法?

auToType问题

首先简单的解释一下为什么序列化中需要 引入AutoType

假设存在一个类,和一个接口:

public interface Father{}
public class Son implements Father{private Integer age;
}

构建出Son类后,json会将类型抹去,只保留顶级接口类型,使之反序列化时拿不到原先的Son类。

因此FastJson中就使用了"@type":"com.xx.xx.Son"

指定json串反序列化时的类型;这种设置在Redis中也有体现,采用的是

{"com.xx.xx.Son","age":1
}

的形式.

那么就带来了一个严重的问题#

在FastJson反序列的过程中,会通过@type构造类,并且根据后续的key调用其setter方法。

那么有经验的人可能有解除过,JAVA中存在着大量的风险类:

  1. com.sun.rowset.JdbcRowSetImpl:这个类在被实例化时会自动连接数据库,存在潜在的安全风险。
  2. java.lang.Runtimejava.lang.Runtime类在被实例化时会自动获取运行时对象,可以用于执行系统命令。
  3. java.lang.ProcessBuilderjava.lang.ProcessBuilder类在被实例化时会自动启动一个进程,可能导致系统被恶意利用。
  4. javax.script.ScriptEngineManager:这个类在被实例化时会加载脚本引擎,存在潜在的安全风险。
  5. java.util.logging.FileHandlerjava.util.logging.FileHandler类在被实例化时会自动创建日志文件,可能导致文件系统被攻击。

拿例子最多,也是早年攻击最频繁的JdbcRowSetImpl一说:

将 JSON字符串

{"@type": "com.sun.rowset.JdbcRowSetImpl","dataSourceName": "rmi://127.0.0.1:8888/Error","autoCommit": true
}

通过抓目标服务器JAVA,WEB应用的请求包,重新reSend一次;

然后jdk会在解析过程中构建 JdbcRowSetImpl 类,实现rmi远程调用的攻击;

不止如此,由于@type指定类的多样性,在获取到对方源码之后。

还可以通过此解析构造的模式直接从项目内部做出高危风险的操作。

因此FastJson在1.2.25版本后,推出完整的AutoType机制,开始了与黑客的 checkAutotype 博弈

CheckAutoType源码问题定位

因为每个版本的FastJson对checkAutoType都有大大小小的优化,贴图的代码版本是1.2.7

第一次过滤

1/

首先在1.2.68 版本中,引入的safeMode,为JSONObject对象初始化的时候会根据是否配置 fastjson.parser.safeMode 值进行开启安全模式,默认为false;在safeMode模式下,无论白名单和黑名单,都不支持autoType,这样可以杜绝反序列化Gadgets类变种攻击,需要通过ParserConfig.getGlobalInstance().setSafeMode(true); 开启

安全模式:取消 @type 指定类解析的机制

2/

下面的类型名>=192,小于<3,意义不明;

不过,围绕名字有一个有趣的地方;

因为事关类解析,所以fastjson没有对 @type:“xxxx”,xxxx为整形时的内容做任何限制;

所以

{"@type":"123"
}

是可以正常解析的

取消指定于3,则是???,意义不明

第二次过滤:

3/

这里为符号过滤,取第一个符号以及最后一个符号进行描述符检查,过滤字符串为 [L

这两个字符的含义是:

  • [ 字符:这个字符在 Java 中通常用于表示数组类型,恶意攻击者可能利用这个字符来构造恶意的数组类型,从而绕过安全检查,执行恶意代码。
  • L 字符:这个字符在 Java 中通常用于表示类的全限定名,恶意攻击者可能利用这个字符来构造恶意的类名,从而触发恶意行为。

1.2.43中进行的修复。

第三次过滤

4/

上一段为最暴力的黑名单过滤;

与黑客斗智斗勇中进化,从过去的类名名单判断,到现在使用hashCode散列存储的方式;

一是掩盖了当前黑名单的类,二是代码性能极大提高;

5/

下面一段先是使用通过typeNameINTERNAL_WHITELIST_HASHCODES 的计算寻址得到的boolean类型判断是否进入黑白名单的判断。

内部代码为,如果在白名单内则直接加载类,结束本次 checkAutoType

否则直接抛出异常

第四次过滤

6/

从deserializers、typeMapping、白名单中获得class;

判断其是否为解析目标时,指定类型的子类;

如果为否,则直接抛出异常;

AutoType关闭时过滤:

直接针对FastJson现有的黑名单以及白名单进行判断

最后一次过滤

针对类型的判断,高危接口:DataSource、RowSet、ClassLoader;

即使黑客前面绕的再好,也不会放开这三个涉及项目加载器,数据库DB的顶级接口;

最后也是判断一个构建出来的类是否已经存在了已经构建完成的构造器,如果存在,则一定是黑客为了绕开检车伪装的类。

因此重复构造直接抛出错误

总结

FastJson的漏洞与更新几乎都是围绕着checkAutoType进行,因为一款JSON化的工具,再本身性能难以再度突破的前提下,保证使用者的安全体验是衡量各个工具之间的重中之重。

但由由于FastJson在国内广泛的使用,而不管目前如何去更新,总有漏洞会为版本买单。

所以很多人也在Git上发起issues抗议这些问题:

讨论度也非常高,也有人不懂@type的存在意义。了解的人能知道,这也是无奈之举,像jackson中也引入了类型的@Class 关键字

大伙也需要给开源者,开源项目更多耐心;

在使用上,可以和开源这个项目的公司[阿里巴巴]一致,默认没有autoType或者直接开启安全模式一刀切

版权声明:本站原创文章,于2024-02-23,乐云一发表
转载请注明:https://leyunone.com/normal-notes/fastJson-warn.html

这篇关于v1.2.70-FastJson的AutoType机制研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1032866

相关文章

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

SpringRetry重试机制之@Retryable注解与重试策略详解

《SpringRetry重试机制之@Retryable注解与重试策略详解》本文将详细介绍SpringRetry的重试机制,特别是@Retryable注解的使用及各种重试策略的配置,帮助开发者构建更加健... 目录引言一、SpringRetry基础知识二、启用SpringRetry三、@Retryable注解

SpringKafka错误处理(重试机制与死信队列)

《SpringKafka错误处理(重试机制与死信队列)》SpringKafka提供了全面的错误处理机制,通过灵活的重试策略和死信队列处理,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、Spring Kafka错误处理基础二、配置重试机制三、死信队列实现四、特定异常的处理策略五

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

Nginx之upstream被动式重试机制的实现

《Nginx之upstream被动式重试机制的实现》本文主要介绍了Nginx之upstream被动式重试机制的实现,可以通过proxy_next_upstream来自定义配置,具有一定的参考价值,感兴... 目录默认错误选择定义错误指令配置proxy_next_upstreamproxy_next_upst

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

一文详解Java Condition的await和signal等待通知机制

《一文详解JavaCondition的await和signal等待通知机制》这篇文章主要为大家详细介绍了JavaCondition的await和signal等待通知机制的相关知识,文中的示例代码讲... 目录1. Condition的核心方法2. 使用场景与优势3. 使用流程与规范基本模板生产者-消费者示例

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.