为什么想写这篇文章,主要是觉得之前虽然我是学习了fastjson,但更多的是拿着一个payload去复现分析调用栈,虽然我也觉得没问题,但是很多细节的部分都被忽略了,再加上这几天躺在家,就想着不如写一篇最适合的文章,一方面检验自己,另一方面也是希望自己能加深对代码的理解,当然这里的内容很多东西只从安全的角度出发,一些无关的也不想多说
简介
Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两个主要接口JSON.toJSONString和JSON.parseObject/JSON.parse来分别实现序列化和反序列化操作。
使用Fastjson进行序列化和反序列化初体验
初步体验可以帮助我们更快提升对fastjson的理解,首先可以简简单单来个学生对象
public class Student { private String name; private boolean alive; public Student() { System.out.println("Student构造函数1"); } public Student(String name, boolean alive) { System.out.println("Student构造函数2"); this.name = name; this.alive = alive; } public boolean isAlive(){ System.out.println("boolean"); return true; } public String getName() { System.out.println("get方法"); return name; } public void setName(String name) { System.out.println("set方法"); this.name = name; } }
首先来序列化对象(SerializerFeature.WriteClassName,是一个设置属性值,设置之后在序列化的时候会多写入一个@type,即写上被序列化的类名,type可以指定反序列化的类,并且调用其getter/setter/is方法)
public static void main(String[] args) { Student y4tacker = new Student("Y4tacker", true); System.out.println(JSON.toJSONString(y4tacker,SerializerFeature.WriteClassName)); }
之后分别调用
String json = "{\"@type\":\"BasicKnow.fastJsonLearning.Student\",\"alive\":true,\"name\":\"Y4tacker\"}"; JSON.parse(json); //JSON.parseObject(json);
可以发现JSON.parse只会调用构造函数与set方法
JSON.parseObject调用构造函数、set、get与is方法,这里
附录
这些东西并不全面,更多是自己在调试代码的时候觉得有意思的,或者觉得对waf绕过有帮助才会列入,这里面会加上一些自己的备注
Feature
不会列所有的Feature,只会列默认的
AllowArbitraryCommas
AllowArbitraryCommas – 允许多重逗号,如果设为true,则遇到多个逗号会直接跳过,感觉有点用处,如果在没升级的前提下简简单单靠waf说不定这个特性可以绕过waf规则,比如下面这个,当然这个逗号也不是随便乱加的,不能破坏原有的一些解析逻辑
String json = "{,,,,,,'@type':\"BasicKnow.fastJsonLearning.Student\",,,,,,,\"age\":233,,,,,,,,,\"name\":\"Y4tacker\"}";