curl --libcurl 生成代码后,第二次请求仍关闭了证书校验
--libcurl生成程序可能沿用前一操作的关闭校验状态。逐次核对perform前的setopt,恢复信任与名称验证,reset后重配完整操作并检查隔离边界。
curl 命令用 --next 分成两次传输,第一次带 --insecure,第二次没有。CLI 在第二次遇到不可信证书会失败,用 --libcurl 生成的 C 程序却可能接受它。需要核对生成程序在两次 curl_easy_perform 之间设置了什么,不能用 CLI 正常就证明示例代码也保持同一校验状态。
正式 curl 8.22.0 的生成路径仍使用同一 easy handle,并可能只输出第一次关闭校验的设置,没有在下一次安全传输前恢复。这里说的是生成代码的状态延续,不是宣称 CLI 的 --next 也把 --insecure 传到了第二次请求。
对照每次 perform 前的选项
保留原命令、curl 版本及生成代码,搜索全部 CURLOPT_SSL_VERIFYPEER、CURLOPT_SSL_VERIFYHOST 和 perform 调用,沿执行顺序阅读。生成时的 local 选项在 CLI 中会重置,但 easy handle 上的 setopt 不会因为 C 源码里分了段就恢复默认值。
这两个方向分别是证书信任和主机名匹配。第一次设为零后,第二次若只有新 URL,不能假定库重新采用默认值。还要核对生成注释中没有自动转换的选项,以及程序链接的实际 libcurl 版本。
生成器的输出是示例,复制进服务前要补齐返回值检查、错误处理和程序自身的资源管理。最后一笔传输成功,不代表前面的请求也成功,更不能证明两次都执行了证书校验。
安全传输前明确恢复两项校验
不需要第一笔不安全请求时,先移除原命令中的 --insecure 并重新审查生成结果。确有隔离测试需求时,让测试与业务请求分开,不把真实秘密发送到不校验证书的测试端点。
维护同一 handle 的程序,需要在安全操作前明确恢复设置。以下辅助函数接收一个已经初始化的 handle:
#include <curl/curl.h>
static CURLcode enable_server_verification(CURL *curl)
{
CURLcode rc = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
if(rc != CURLE_OK)
return rc;
return curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
}
调用方必须检查这个函数的返回值,非 CURLE_OK 时停止该笔传输并走原程序的错误清理路径。它不负责初始化、执行或清理 handle。URL、回调、请求头、认证、CA 和其他必要设置仍应由原程序完整配置。
VERIFYPEER 的 1L 恢复可信 CA 验证,VERIFYHOST 的 2L 恢复目标名称检查。私有 CA 用已核实的信任材料配置,不能因报证书错误又把任一项设为零。
reset 之后必须重新配置完整操作
另一个方式是在操作边界 curl_easy_reset,然后重新设置本次需要的全部选项。但 reset 会恢复 URL、回调和其他配置的默认值,只加一个 URL 并不保证保留了原来的业务行为。
它也不会清空所有身份与连接状态:存活连接、会话 ID 缓存、DNS 缓存、Cookie、share 和 alt-svc 信息仍可保留。需要完全隔离不可信测试与正常请求时,应审查 handle、共享池和持久状态的范围,而不是把 reset 称为完整隔离。
只修两个 TLS 标志也不证明生成器的其他 local 选项都已正确恢复。逐项核对两笔操作的意图,包括请求方法、请求体、头部、代理和认证,不用一次成功响应掩盖别的状态延续。
验收要包含该失败的证书
在隔离且不发送秘密的测试中,用受控的不可信证书和名称不匹配端点检查安全操作应失败,再确认获准的有效目标能成功,并执行原有业务校验。编译成功或 HTTPS 返回 200 都不能单独证明名称与信任验证开启。
新的候选补丁、关闭的 issue 或合入记录,不能代替正在使用的正式版本审查。准备升级时核对具体发行代码和生成结果,保留源代码与构建回退记录;撤回修改也要保留安全校验,不能把恢复零值作为业务回退。


