一、基础知识
Fastjson介绍:
fastjson是阿里巴巴开源的JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。即fastjson的主要功能就是将Java Bean序列化成JSON字符串,这样得到字符串之后就可以通过数据库等方式进行持久化了。
Fastjson序列化/反序列化原理
fastjson漏洞的本质是一个 java 的反序列化漏洞,由于引进了 AutoType 功能,fastjson 在对 json 字符串反序列化的时候,会读取到 @type 的内容,将json内容反序列化为java对象并调用这个类的setter方法。
那么为啥要引进Auto Type功能呢?
fastjson在序列化以及反序列化的过程中并没有使用Java自带的序列化机制,而是自定义了一套机制。其实,对于JSON框架来说,想要把一个Java对象转换成字符串,可以有两种选择:
1.基于setter/getter
2.基于属性(AutoType)
基于setter/getter会带来什么问题呢,下面举个例子,假设有如下两个类:
class Apple implements Fruit {
private Big_Decimal price;
//省略 setter/getter、toString等
}
class iphone implements Fruit {
private Big_Decimal price;
//省略 setter/getter、toString等
}
实例化对象之后,假设苹果对象的price为0.5,Apple类对象序列化为json格式后为:
{
"Fruit":{
"price":0.5}}
假设iphone对象的price为5000,序列化为json格式后为:
{
"Fruit":{
"price":5000}}
当一个类只有一个接口的时候,将这个类的对象序列化的时候,就会将子类抹去(apple/iphone)只保留接口的类型(Fruit),最后导致反序列化时无法得到原始类型。本例中,将两个json再反序列化生成java对象的时候,无法区分原始类是apple还是iphone。
为了解决上述问题:fastjson引入了基于属性(AutoType),即在序列化的时候,先把原始类型记录下来。使用@type的键记录原始类型,在本例中,引入AutoType后,Apple类对象序列化为json格式后为:
{
"fruit":{
"@type"