json数据格式转化问题


FastJson数据格式化问题以及漏洞

前言

​ json数据是java中常见的数据格式,形成类似于map+数组的数据结构,阿里也为此专门设计了有关java的fastjson,足以可见其中对json的业务需求,具体的发展历史不多赘述。最近业务上对此的使用也颇多,干脆一次性来个简单的总结。

​ 本人主要钻研在后端,前端有所学习,但谈不上工程级别,为此叙述的过程中对前端的说法不一顶准确,多多见谅

对象和json的区别

​ 这和主流的框架处理方式有关,这边讨论java的spring框架

  • 在后端用对象封装好之后,留给前端的就是json数据,字符串型的使用“”括住,数值型的则没有

    但是前端传回时,就不再有引号了(缺少转义符),对此json转化最会出错

  • 当然,后端也可以使用json字符串直接返回给前端,在fastJson中toJsonString,返回给前端的数据则会用反斜杠 \ 来区分引号中的引号(此处也可以在fastJson的配置信息中更改,变成和前者一样的标准json)

fastJson的用法

  • jsonObject

    类似于map结构,可以存入各式各样的对象在value中,fastJson会自行形成对应的结构

  • JSON.parseObject

​ 从字符串解析 JSON 对象

  • JSON.parseArray

​ 从字符串解析 JSON 数组

  • JSON.toJSONString(obj/array)

    将 JSON 对象或 JSON 数组转化为字符串

  • JSONObject.getObject(String key, Class clazz)

​ 将json转为对象

  • json转列表

    JSONArray students = jsonObject.getJSONArray("list");
    List<Student> students = JSONObject.parseArray(students.toString(), Student.class);

问题

​ fastJson的主要特点就是序列化比较快了,是已知的几个(字符串方式)序列化方式中最快的,为了实现快的目的,使用了全局缓存、仅仅序列父类类型(借用AutoType曲线救国)、避免使用反射、算法优化等等

​ fastJson的问题还是比较出名的了,原因就主要出在这个“快”上面:fastJson是通过遍历实体类中的所有getter方法来取值,对比gosn是通过反射遍历成员变量的属性,因此前者它就很快了。

​ 问题就来了:当一个类中包含了一个接口(或抽象类)的时候,在使用fastjson进行序列化的时候,会将子类型抹去,只保留接口(抽象类)的类型,使得反序列化时无法拿到原始类型。

​ 对此fastJson就引入了AutoType,使用全类名的方式,将指定子类的类型,因此黑客仅仅需要更改

  1. AutoType类型的值
  2. 从上文中提过的更改全局缓存中的type值
  3. 利用异常绕过序列化校验等方式,重写type的值

​ 指定加载特定的类,比如com.sun.rowset.JdbcRowSetImpl(远程调用)等,黑客甚至可以去指定自己要想执行的系统指令。尽管经历了围绕AutoType无数次的博弈、修改,目前都有了对应的修复,但是最终还是额外提供了一种方式,即safeMode,简单得说,就是禁用AutoType

补充:

​ 个人比较喜欢在浏览json数据时使用vscode新建json数据,格式化后查看非常方便直观


文章作者: hyy
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hyy !
  目录