Apple SecTrust遗留路径证书验证漏洞分析

本文详细分析了curl库在特定配置下存在的证书验证漏洞,当启用USE_APPLE_SECTRUST编译并在旧版Apple系统运行时,会导致不受信任的证书被错误接受,可能造成中间人攻击风险。

curl | Report #3374554 - Apple SecTrust遗留路径在接受不受信任证书漏洞

摘要

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

[关于是否使用AI发现问题的声明] 本报告是在AI代码分析工具的协助下准备的;核心诊断和范围通过传统软件、手动代码检查和AI相结合的方式进行验证。

受影响版本

在当前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;

调用Apple SecTrust验证的行为门:

OpenSSL:

1
2
3
4
5
6
if(!verified &&
   conn_config->verifypeer && ssl_config->native_ca_store &&

  result = ossl_apple_verify(..., &verified);
  ...
}

GnuTLS:

1
2
3
4
5
if(!verified && ssl_config->native_ca_store &&
   (verify_status & GNUTLS_CERT_SIGNER_NOT_FOUND)) {
  result = glts_apple_verify(..., &verified);
  ...
}

影响

摘要:

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

范围注意事项:

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

时间线

giant_anteater 向curl提交报告 - 2025年10月7日,下午3:37(UTC)

bagder (curl工作人员) 发表评论 - 2025年10月7日,下午3:39(UTC)

谢谢! 这是尚未在任何版本中发布的代码,因此根据定义我们不将其视为安全问题。我认为最好将其归档为"普通错误"。

giant_anteater 发表评论 - 2025年10月7日,下午3:40(UTC)

好的,将包含在我将发送的一批普通错误中。

bagder (curl工作人员) 关闭报告并将状态更改为Informative - 2025年10月8日,上午7:39(UTC)

认为不是安全问题,因为它尚未在版本中发布。仍然是一个潜在的错误!

bagder (curl工作人员) 请求披露此报告 - 2025年10月8日,上午7:39(UTC)

根据项目的透明政策,我们希望所有报告都被披露并公开。

bagder (curl工作人员) 披露此报告 - 14天前

报告详情

项目 详情
报告时间 2025年10月7日,下午3:37(UTC)
报告者 giant_anteater
报告对象 curl
报告ID #3374554
状态 Informative
严重程度 High (7 ~ 8.9)
披露时间 2025年10月9日,上午6:22(UTC)
弱点 Improper Certificate Validation
CVE ID None
赏金 None
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计