[Java安全]Fastjson>=1.2.36$ref引用可触发get方法分析

Posted Y4tacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java安全]Fastjson>=1.2.36$ref引用可触发get方法分析相关的知识,希望对你有一定的参考价值。

写在前面

平时我们在处理fastjson反序列化的时候,如果我们想要执行属性的get方法,而如果只有JSON.parse怎么办
我们知道JSON.parse可以套一层parseObject实现对get方法的调用,但说这个也没有必要继续本篇的介绍了,这里介绍另一种,废话不多说开始分析

JSONPath语法

看文档https://goessner.net/articles/JsonPath/,重点关注下这个

利用演示

人比较不老实,喜欢骚东西,这里执行下命令

public class Test {
    private String cmd;

    public String getCmd() throws IOException {
        Runtime.getRuntime().exec(cmd);
        return cmd;
    }

    public void setCmd(String cmd) {
        this.cmd = cmd;
    }
}

触发

    public static void main(String[] args) {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String payload = "[{\\"@type\\":\\"com.yyds.Test\\",\\"cmd\\":\\"calc\\"},{\\"$ref\\":\\"$[0].cmd\\"}]";
        Object o = JSON.parse(payload);
    }

最爱的计算器

$ref引用触发get方法分析

简简单单引入依赖

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

老规矩拉到底,看看调用栈再分析

跟进handleResovleTask函数

获取$ref
至于如果你问在哪里设置的在DefaultJSONParser#parse()

ok,不说废话,继续看下去,满足条件跟进

这里面没有返回null

接下来重点来了,我们看看JSONPath.eval函数干了什么

跟进compile

根据path生成并返回一个JavaPath对象

继续看看eval

这里有一个init函数执行

我们重点关注这个explain函数,把$refvalue解析成Segment,这个Segment是定义在JSONPath类的一个接口,具体看他的过程

这里初始化长度是8很好奇吗
因为实现segment接口的类只有八个


ok,继续看看这个readSegement,获取.后面的值
这里通过readName获取到cmd

内部实现靠循环追加到StringBuilder后面

后面通过浅拷贝赋值返回
接下来按顺序执行前面explain生成的Segment array


跟进JSONPath.getPropertyValue

继续跟进

跟进


后面就是用反射调用get方法了


分析完毕

解释为什么1.2.36前的版本不行

我们知道关键在于JSONPath.eval方法的调用
我们来对比一下,前为1.2.36版本,后为1.2.35版本


限制了refValue的值不能为null,并且必须是JSONObject对象,那就结束了

以上是关于[Java安全]Fastjson>=1.2.36$ref引用可触发get方法分析的主要内容,如果未能解决你的问题,请参考以下文章

[Java安全]fastjson学习

[Java安全]fastjson学习

[Java安全]fastjson学习

[Java安全]fastjson学习

[Java安全]fastjson学习

Java安全之FastJson JdbcRowSetImpl 链分析