【缺陷周话】第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 修复要点

  1. 使用SSLContext创建安全套接字上下文
  2. 指定TLS协议版本
  3. 使用HttpsURLConnection替代普通URLConnection
  4. 显式设置安全套接字工厂

5. 最佳实践建议

  1. 避免使用默认连接:

    • 不要直接使用默认的URLConnection
    • 优先使用HttpsURLConnection
  2. 证书验证处理:

    • 实现自定义的证书验证逻辑
    • 对证书进行严格的主机名匹配检查
  3. 安全协议选择:

    • 明确指定安全协议版本(如TLS 1.2+)
    • 禁用不安全的协议(如SSLv3)
  4. 密钥库管理:

    • 限制信任的CA证书范围
    • 定期更新和维护信任的证书列表

6. 相关CVE案例

  1. CVE-2019-13050:

    • 影响: sks-keyserver与GnuPG 2.2.16之间的交互
    • 风险: 证书垃圾邮件攻击可能导致持续拒绝服务
  2. CVE-2018-10936:

    • 影响: PostgreSQL JDBC驱动(<42.2.5)
    • 问题: 未提供主机名验证器时,攻击者可伪装成可信服务器

7. 检测与验证

7.1 静态检测要点

  • 查找直接使用URL.openConnection()的代码
  • 检查是否使用了HttpsURLConnection
  • 验证是否设置了自定义的SSLSocketFactory
  • 检查证书验证逻辑是否完整

7.2 动态测试方法

  • 使用中间人代理工具(如Burp Suite)测试证书验证
  • 尝试使用自签名证书进行连接测试
  • 验证异常证书是否被正确拒绝

8. 扩展阅读

  1. OWASP相关指南:

    • OWASP Transport Layer Protection Cheat Sheet
    • OWASP Certificate and Public Key Pinning Guide
  2. Java安全文档:

    • JSSE (Java Secure Socket Extension)参考指南
    • Java Cryptography Architecture文档
  3. 相关标准:

    • 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
不安全的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) 3.2 缺陷分析 第23行使用默认的URLConnection建立SSL/TLS连接 未对证书进行任何验证处理 自动信任所有CA签名的证书,存在中间人攻击风险 4. 修复方案 4.1 修复代码(Java) 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