苹果SecTrust遗留路径漏洞分析:curl在旧系统上错误接受不受信任证书

本文详细分析了curl库在启用USE_APPLE_SECTRUST编译时存在的安全漏洞,该漏洞导致在macOS 10.14和iOS 12之前的系统上错误接受不受信任的TLS证书,可能引发中间人攻击风险。

漏洞概述

当libcurl启用USE_APPLE_SECTRUST编译并在缺乏SecTrustEvaluateWithError的Apple操作系统版本(macOS <10.14 / iOS <12)上运行时,遗留验证路径错误地将OSStatusSecTrustResultType进行比较,从未检查SecTrust结果。这可能导致接受不受信任的证书。

受影响版本

在当前master版本(截至2025-10-07)上重现。影响启用USE_APPLE_SECTRUST并在macOS <10.14 / iOS <12上运行的构建。该缺陷位于lib/vtls/apple.c中,与TLS后端选择无关(当使用原生CA存储时,通过OpenSSL或GnuTLS到达)。

复现步骤

代码验证(任何现代macOS):

  1. 检查lib/vtls/apple.c第263-275行的易受攻击代码
  2. 观察类型混淆:status(OSStatus)与kSecTrustResultType枚举值比较
  3. 创建演示逻辑错误的测试程序(参见验证工件)
  4. 创建不受信任的证书并验证系统curl拒绝它

运行时利用(需要macOS <10.14或iOS <12):

注意:这需要实际的遗留系统。在现代macOS上使用-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13构建不会在运行时触发该错误,因为存在__builtin_available检查。

  1. 在运行macOS 10.13.6(High Sierra)或更早版本的系统上构建curl:
1
2
cmake -DUSE_APPLE_SECTRUST=ON -DCURL_USE_OPENSSL=ON \
      -DCMAKE_BUILD_TYPE=Release .
  1. 创建不受信任的证书(如所述)
  2. 启动测试服务器:openssl s_server -accept 8443 -www -key leaf.key -cert leaf.pem
  3. 测试:./src/curl -v https://localhost:8443/

预期安全行为:连接被拒绝 实际错误行为:连接成功

无遗留硬件的替代验证:

由于该错误是明显的逻辑错误(比较错误的变量),可以通过以下方式确认:

  • 静态代码分析(第270-271行比较status而不是sec_result)
  • 逻辑演示(status=0从不等于kSecTrustResultUnspecified=4)
  • 当条件失败时result保持CURLE_OK的事实

问题代码

遗留回退使用SecTrustEvaluate;将status与SecTrustResultType比较而不是检查sec_result

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#ifndef REQUIRES_SecTrustEvaluateWithError
SecTrustResultType sec_result;
status = SecTrustEvaluate(trust, &sec_result);

if(status != noErr) {
  failf(data, "Apple SecTrust verification failed: error %i", (int)status);
}
else if((status == kSecTrustResultUnspecified) ||
        (status == kSecTrustResultProceed)) {
  /* "unspecified" means system-trusted with no explicit user setting */
  result = CURLE_OK;
}
#endif /* REQUIRES_SecTrustEvaluateWithError */

正确的现代代码路径(仅在10.14+/iOS 12+上可用):

1
2
result = SecTrustEvaluateWithError(trust, &error) ?
         CURLE_OK : CURLE_PEER_FAILED_VERIFICATION;

影响

在受影响的配置(USE_APPLE_SECTRUST构建在pre-10.14 Apple OS上运行并启用原生CA验证)下,攻击者可以绕过TLS证书验证。这使得中间人拦截成为可能,危及HTTPS和其他TLS保护传输的机密性和完整性。

范围注意事项:

  • 功能是编译时门控(USE_APPLE_SECTRUST),在CMake中默认关闭
  • 运行时可达性取决于后端条件(OpenSSL"无法获取本地颁发者证书"或GnuTLS"未找到签名者")
  • 该错误仅影响缺乏SecTrustEvaluateWithError的较旧Apple OS版本;现代Apple OS使用正确的代码路径

项目响应

curl工作人员bagder评论表示: “这还没有在任何版本中发布的代码,因此根据定义,我们不将其视为安全问题。我认为最好将其归档为’普通错误’。”

报告状态已更改为"Informative",并已根据项目透明度政策公开披露。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计