FastJson
升级到1.2.70
说明author
: Vic.xu
Date
:20200601
近日,阿里云应急响应中心监测到fastjson爆发新的反序列化远程代码执行漏洞,黑客利用漏洞,可绕过autoType限制,直接远程执行任意命令攻击服务器,风险极大。
fastjson采用黑白名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的反序列化Gadgets类时,在autoType关闭的情况下仍然可能可以绕过黑白名单防御机制,造成远程命令执行漏洞。经研究,该漏洞利用门槛较低,可绕过autoType限制,风险影响较大。阿里云应急响应中心提醒fastjson用户尽快采取安全措施阻止漏洞攻击。
- fastjson <=1.2.68
- fastjson sec版本 <= sec9
升级到最新版本1.2.69或者更新的1.2.70版本。
fastjson
在1.2.68及之后的版本中引入了safeMode
,配置safeMode
后,无论白名单和黑名单,都不支持autoType
,可一定程度上缓解反序列化Gadgets类变种攻击(关闭autoType
注意评估对业务的影响)
在代码中配置
ParserConfig.getGlobalInstance().setSafeMode(true)
;
加上JVM
启动参数
-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功能的绕过,绕过细节可参考(https://www.anquanke.com/post/id/181874),
基于工银当前使用的版本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
的检查流程
准备可绕过检测的字符串
执行字符串的反序列化
JSONObject obj = JSON.parseObject(str);
执行结果为报错
……..set property error, autoCommit
……..JdbcRowSet (连接) JNDI 无法连接
说明执行了数据库连接操作,以及执行了setAutoCommit
;,证明绕过了autotype
的禁用;
绕过的原理,参考https://www.anquanke.com/post/id/181874;大概意思为:
json
使用的相关说明Jackson
MappingJackson2HttpMessageConverter
(也即Jackson
)@ResponseBody
注解返回响应体的内容时把对象转为是json字符串(序列化);这一点在本项目中大量使用,绝大多数ajax请求都是都经过此json序列化;@RequestBody
注解,接收前端的json字符串,并把json字符串序列化程对象, 在本项目中使用频率极低(通过搜索只发现一处)fastjson
在本项目中的使用只搜索反序列化,因为序列化不存在安全问题
JSON.parse
在本项目中搜索到的结果为19 处JSONObject.parse
在本项目中搜索到的结果为2处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配置。
2020年6月1日