【缺陷周话】第52期——不安全的SSL:过于广泛的信任证书
字数 1614 2025-08-18 11:38:56
不安全的SSL:过于广泛的信任证书 - 代码审计教学文档
1. 缺陷概述
CWE ID: 297 (Improper Validation of Certificate with HostMismatch)
缺陷本质: 当程序默认接受由证书颁发机构(CA)颁发的所有证书而屏蔽了安全校验逻辑时,可能导致中间人攻击风险。
危害:
- 基于恶意证书提供的信任可能允许欺骗或重定向攻击
- 攻击者可以拦截CA的SSL/TLS信息流进行中间人攻击
- 2018-2019年间CVE中有3个相关漏洞记录
2. 技术背景
2.1 SSL/TLS证书验证机制
- 证书颁发机构(CA)为每个公开密钥发放数字证书
- 证书是通用网络通信工具的必要组件
- 近年来CA盗用事件增加,导致即使CA签名的证书也可能是恶意的
2.2 常见错误实现
- 使用默认的URLConnection建立SSL/TLS连接
- 未对SSLSocketFactory进行适当处理
- 默认信任Android密钥库中所有CA签名的证书
3. 缺陷代码示例与分析
3.1 缺陷代码(Java)
// 建立URL连接并读取输入流数据
URL url = new URL("https://example.com"); // 22行
URLConnection urlConnection = url.openConnection(); // 23行缺陷位置
InputStream in = urlConnection.getInputStream(); // 24行
// 读取输入流内容
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
3.2 缺陷分析
- 第23行使用默认的URLConnection建立SSL/TLS连接
- 未对证书进行任何验证处理
- 自动信任所有CA签名的证书,存在中间人攻击风险
4. 修复方案
4.1 修复代码(Java)
// 创建SSL上下文
SSLContext sslContext = SSLContext.getInstance("TLS"); // 29行
sslContext.init(null, null, null); // 30行初始化
// 建立HTTPS连接
HttpsURLConnection httpsConnection = (HttpsURLConnection)url.openConnection();
httpsConnection.setSSLSocketFactory(sslContext.getSocketFactory()); // 33行设置安全套接字工厂
// 读取输入流
InputStream in = httpsConnection.getInputStream();
4.2 修复要点
- 使用
SSLContext创建安全套接字上下文 - 指定TLS协议版本
- 使用
HttpsURLConnection替代普通URLConnection - 显式设置安全套接字工厂
5. 最佳实践建议
-
避免使用默认连接:
- 不要直接使用默认的
URLConnection - 优先使用
HttpsURLConnection
- 不要直接使用默认的
-
证书验证处理:
- 实现自定义的证书验证逻辑
- 对证书进行严格的主机名匹配检查
-
安全协议选择:
- 明确指定安全协议版本(如TLS 1.2+)
- 禁用不安全的协议(如SSLv3)
-
密钥库管理:
- 限制信任的CA证书范围
- 定期更新和维护信任的证书列表
6. 相关CVE案例
-
CVE-2019-13050:
- 影响: sks-keyserver与GnuPG 2.2.16之间的交互
- 风险: 证书垃圾邮件攻击可能导致持续拒绝服务
-
CVE-2018-10936:
- 影响: PostgreSQL JDBC驱动(<42.2.5)
- 问题: 未提供主机名验证器时,攻击者可伪装成可信服务器
7. 检测与验证
7.1 静态检测要点
- 查找直接使用
URL.openConnection()的代码 - 检查是否使用了
HttpsURLConnection - 验证是否设置了自定义的
SSLSocketFactory - 检查证书验证逻辑是否完整
7.2 动态测试方法
- 使用中间人代理工具(如Burp Suite)测试证书验证
- 尝试使用自签名证书进行连接测试
- 验证异常证书是否被正确拒绝
8. 扩展阅读
-
OWASP相关指南:
- OWASP Transport Layer Protection Cheat Sheet
- OWASP Certificate and Public Key Pinning Guide
-
Java安全文档:
- JSSE (Java Secure Socket Extension)参考指南
- Java Cryptography Architecture文档
-
相关标准:
- RFC 5280: Internet X.509 Public Key Infrastructure
- RFC 6125: Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 Certificates