cURL版本更新录(202x)
2022-10-28 12:10:46 阿炯

本文是从cURL的产品主页分离出来的,专门用于该发行版本的更新记录,截止到2030年之前。cURL 是一个提供一个库(libcurl)和命令行工具(curl),用于使用各种网络协议传输数据的开源项目。该名字代表了 "Client URL"。


最新版本:7.x
主要改进内容:
添加 CURLOPT_HAPROXYPROTOCOL,支持 HAProxy PROXY 协议
为命令行工具添加 --haproxy-protocol
添加 CURLOPT_DNS_SHUFFLE_ADDRESSES,随机播放返回的 IP 地址
FTP: 关机响应缓冲区溢出 CVE-2018-1000300
RTSP: 错误标题缓冲区过度读取 CVE-2018-1000301
FTP: 在递归回调检测中修复打字错误
Retry-after:一些服务器不能或不愿意响应时,返回的一个标准 HTTP 报头,表示在几秒钟后,或在未来的某个时间,请求可能会得到响应
HTTP/3:这个实验特性在默认情况下是禁用的,但是可以通过设置来启用
并行传输:此版本可以使用 curl 工具的新选项 -Z / –parallel 进行并行传输
curl_multi_poll:这是一个新的函数,它非常类似 curl_multi_wait。它解决了一个问题:在 libcurl 根本没有文件描述符等待的情况下,应用程序应该做些什么
SASL authzid:此版本中,在使用 SASL 身份验证时,curl 和 libcurl 可以提供 authzid 字段
在 Windows 上 .netrc 和 .curlrc:此版本,curl 和 libcurl 将检查和使用这些文件的点前缀版本,即使 Windows 上也是如此
asyn-thread: 创建要等待的套接字对
修复一个回归:使 curl 在使用代理进行多级身份验证(如 HTTPDigest)时,不能正确地使用 URL 中的凭据
将代码移到 ssh 后端的 vssh 中,默认情况下禁用 HTTP/0.9
7.7版本添加了原生的 JSON 支持,使用参数 --write-out,可以将元数据直接输出为 JSON 对象;另外还增加了对 MQTT 协议的支持,不过目前处于实验性阶段;schannel 添加了 --ssl-revoke-best-effort 以允许“尽力而为”吊销检查,同时添加选项:CURLSSLOPT_REVOKE_BEST_EFFORT。
此外还修复了众多 bug,详情可查看更新日志

最新版本:7.77
cURL 7.77.0 已于2021年5月28日发布,这是该软件的第 200 次版本发布,因此官方也将 7.77.0 版本命名为 200 OK。它恰好与我们超过 900 个提交者和超过 2400 个项目的贡献者相吻合。这也是有史以来第一个我们在 RELEASE-NOTES 中感谢 80 多人帮助我们发布的版本,并且我们 在bug-bounty 计划中创造了两个新的记录:对一个 bug 的最大单次支付(2000 美元)和在一个发布周期内的最大总支付 3800 美元。
第 200 次发布
0 个新的 public libcurl function (total: 85)
2 个新的 curl_easy_setopt() 选项 (total: 290)
2 个新的 curl 命令行选项 (total: 242)
82 contributors, 44 new (total: 2,410)
47 authors, 23 new (total: 901)
3 个安全修复:
CVE-2021-22901: TLS session caching disaster。这是 OpenSSL 后端代码中的一个 Use-After-Free,在 absolutely worst 的情况下会导致 RCE,即远程代码执行。这个漏洞是最近才出现的,很难被利用,但官方建议用户应该立即升级或打补丁。从 TLS 服务器发送与 TLS 会话相关的信息时,如果以前使用它的传输已经完成并消失,则会发生此问题。这就是那个价值 2000 美元的 bug。
CVE-2021-22898: TELNET stack contents disclosure。当 libcurl 接受自定义 TELNET 选项发送至服务器时,输入解析器存在缺陷,可被利用来让 libcurl 代替堆栈发送内容。这个漏洞价值 1000 美金。
CVE-2021-22897: schannel cipher selection surprise。在 Schannel 的后端代码中,为一次 transfer 所选择的密码被存储在一个静态变量中。这导致一个传输的选择削弱了单组传输的选择,可能会在不知不觉中影响其他连接,使其安全等级低于预期。这个漏洞价值 800 美金。

Make TLS flavor explicit:curl configure 脚本不再默认选择一个特定的 TLS 库。现在当使用 configure 构建 curl 时,需要选择要使用的库。
No more SSL:curl 现在不再有支持 SSLv2 或 SSLv3 的痕迹。这些古老而不安全的 SSL 版本已经被各地的 TLS 库默认禁用,但现在即使在特殊构建中也无法激活它们,从 curl 工具和库中都删除了。
HSTS in the build:此前版本中曾带来了对 HSTS 的实验性支持,现在已去掉了实验性的标签,并在构建时默认启用,以便大家更容易地使用它。
In-memory cert API:为 libcurl 引入 API 选项,允许用户在内存中指定证书,而不是使用文件系统中的文件。参见 CURLOPT_CAINFO_BLOB。
Version output:curl -V 输出的 first line 得到了更新:libcurl 现在包括了 OpenLDAP 及其在构建中使用的版本;然后 curl 工具可以添加 libmetalink 及其在构建中使用的版本。
curl_mprintf: add description:在 API 中提供了 *printf() clone functions,同时首次提供了一个明确的使用手册页。
CURLOPT_IPRESOLVE: 防止使用错误的 IP 版本:官方指出,这个选项比以前更严格了一些。以前,它对现有的连接比较宽松,倾向于重复使用而不是再次解析,但是从现在开始,这个选项确保只使用请求 IP 版本的连接。这允许应用程序在需要时使用不同的 IP 版本明确地创建两个独立的连接到同一个主机,在以前,libcurl 则不会轻易让你这么做。
忽略 curl_easy_send 中的 SIGPIPE
Several HTTP/2-fixes:在这个版本中,HTTP/2 模块中提到了不少于 6 个独立的修复措施。一些潜在的内存泄漏,但也有一些更多的行为改进。最重要的可能是将传输相关的错误代码从连接结构移至传输结构,因为它容易受到 race condition 的影响,可能会导致错误。另一个相关的修正是,libcurl 不再强行断开一个传输得到 HTTP_1_1_REQUIRED 结果的连接。
Partial CONNECT requests:当发送给代理的 CONNECT HTTP 请求没有全部在单个 send() 调用中发送时,curl 会失败。不过令人费解的是,这个 bug 在早期的时候并没有被发现或报告,却在最近一次发出一个大于 16KB 的 CONNECT 请求时被发现了。

更多详情可查看此处

最新版本:7.79
cURL 7.79.0 现已于2021年9月中旬发布,具体更新内容如下:
CVE-2021-22945 是 MQTT 代码中的一个 double-fre 缺陷。如果你用它来发送 MQTT,则需要给你的旧 curl 打上补丁或升级到这个版本。
CVE-2021-22946 是几个协议(IMAP、POP3 和 FTP)的响应处理中的一个错误,它绕过了强制的 TLS 检查.因此,即使是明确告知需要 TLS 的传输也会意外地以 clear text 方式悄悄进行。
CVE-2021-22947 允许 mitm 攻击者在 TLS 升级前将数据注入 FTP、IMAP、POP3 或 SMTP 的协议流中,从而使 curl 接受该数据并在升级到 TLS 后使用它。不受信任的数据就会溜进去,并被当作受信任的数据处理。

bearssl TLS 后台的现在也支持 CURLOPT_CAINFO_BLOB 选项,这样 CA 证书就可以很容易地由应用程序在内存中提供。
curl 中的 cookie 引擎现在认为 http://localhost 是安全的,因此被标记为"secure"的 cookie 将通过它发送--即使不使用 HTTPS。这样做是因为 curl 从不久前开始确保 localhost 始终是 truly local。
Secure Transport TLS backend 用户现在可以使用 CURLINFO_CERTINFO 来提取关于服务器证书链的信息。

问题修复
使用 ares_getaddrinfo():当你构建 c-ares 名称解析器后端时,curl 现在会使用这个函数来获得对 IPv4+IPv6 的改进处理。这也使得对 c-ares 的要求提高到 1.16.0。
hyper works better:1xx responses、Transfer-Encoding 和更多的问题都得到了修复。对 hyper 构建禁用的测试数量比以前更少了,但在它脱离实验性之前,仍有很多工作要做。
cmake 构建:避免在 macOS 上使用 poll()。
configure:也检查 OpenSSL pkg-config 文件中的 lib64。这有助于 configure 找到 OpenSSL v3 installs。
curl.1:为每个选项提供示例。现在的文档必须为 curl 提供的每个命令行选项提供至少一个命令行实例。
HTTP 1.1:不允许超过 3 位的响应代码。
HTTP 1.1:如果使用任何 transfer-encoding,忽略 content-length。
http_proxy:发送请求时只等待可写的套接字。
支持 mbedTLS 3.0.0。
禁止 strerror。
邮件列表从 cool.haxx.se 迁移到 lists.haxx.se。

详情可查看此处

最新版本:7.8x
curl 7.82.0 现已于2022年3月上旬发布,具体更新内容如下:
有了新的 --json 命令行选项,使得从命令行和 shell 脚本发送 JSON 变得更加方便。
curl 支持大量不同的 TLS 库,但现在数量减少了一个(到 13 个),因为官方正式放弃了对 MesaLink 的支持。这个库已经不再开发,所以不鼓励用户使用。
对 bearssl 后端进行了三个值得注意的修复:针对证书过期、不完整的 CA 证书和会话恢复。
strlen 调用删除
configure 要求 –with-nss-deprecated
删除一些比较敏感的命令行参数
NPN 已弃用
允许 CURLOPT_HTTPHEADER 更改“:scheme”
删除对 TPF、Netware、vxWorks、CURL_DOES_CONVERSIONS 的支持
允许用户回调调用 curl_multi_assign
http3:quiche 和 ngtcp2 修复
禁用 FTP 时减少内存使用
检查 ~/.config/curlrc:
命令行工具提供了一组函数来控制 DNS 的具体细节,由于这些选项只有在 libcurl 被构建为使用 c-ares 时才起作用,而如果它被构建为使用另一个解析器后端则完全不起作用,现在当 libcurl 不能执行这些选项时,当使用这些选项之一时,curl 将正确返回错误。
在 host name 中保留 trailing dot
wolfssl:当 SSL_read() 返回 0 时检查错误
更多详情可查看此处

-rate:这个新的命令行选项 rate 限制了每个时间段的传输次数。
弃用 -random-file 和 -egd-file:这两个选项已经有很长一段时间没有人使用了,从现在开始,它们已经没有任何功能了,使用它们不会有任何效果。
curl_global_init () 是线程安全的:即该函数在大多数平台上都是线程安全的。
curl_version_info: 增加了 CURL_VERSION_THREADSAFE:可以检查全局 init 在特定的 libcurl 构建中是否是线程安全的。
CURLINFO_CAPATH/CAINFO: 获取默认 CA 路径:由于这些值的默认值通常是在构建时计算和设置的,应用程序可能会想要弄清楚它们默认设置为什么。
CURLOPT_SSH_HOSTKEYFUNCTION:对于启用了 libssh2 的构建,你现在可以为主机密钥验证设置一个回调。
弃用 RANDOM_FILE 和 EGDSOCKET:CURLOPT_RANDOM_FILE 和 CURLOPT_EGDSOCKET 选项不再有任何作用,它们已经很久没有被任何应用程序使用了。
unix sockets to socks proxy:现在可以告诉 (lib) curl 使用 unix 域套接字连接到 SOCKS 代理,而不是传统的 TCP。

错误修复
改进了 cmake 对 libpsl 和 libidn2 的支持
使仓库符合 REUSE 标准
headers API 不再是试验性的了
支持 .netrc 中的引号字符串
对不区分大小写的字符串比较进行了优化

cURL 7.86 于2022年10月下旬正式发布,添加实验性 WebSocket 支持、移除 NPN 支持。

已移除 NPN 支持:curl 不再支持使用 NPN 协商 HTTP/2。执行此操作的标准方法长期以来一直是 ALPN,且浏览器几年前就取消了对 NPN 的支持。
WebSocket API:此版本中包含一个实验性 WebSocket API ,它以三个新功能和一个新的 setopt 选项来控制行为,其介绍可见此处

一些已解决的问题:
aws_sigv4 标头计算代码进行了重大改革
curl 手册页详细说明了每个选项的多用途,100 多个文档拼写修复
弃用带有小 curl_off_t 的构建,这个版本的  curl 不再支持在没有 64 位数据类型的系统上构建
ngtcp2 配置选项默认为 “否”,需要明确要求在构建中启用 ngtcp2
拒绝带有 TAB 字符的 cookie 名称或内容,名称或内容中带有标签的 Cookie 无法互操作, curl 将它们保存到磁盘时会出问题,因此拒绝
对于带有 gcc + want 警告的构建,设置 gnu89 标准,为了更好地确保兼容性
使用 -O2 作为默认优化配置中的 clang
ctype 函数转换为仅宏,用宏替换了整个函数族
使 nghttp2 对 HTTP/2 中的字段空白不那么挑剔,如果使用新的 nghttp2 库构建,curl 对标题字段后的尾随空格不那么挑剔
使用 URL 解码的用户名进行 .netrc 解析,这种回归使得 curl 在使用 .netrc 文件查找相应密码时,无法正确解码 URL 中提供的用户名
使 certinfo 可用于 QUIC,CURLOPT_CERTINFO 选项现在适用于 QUIC/HTTP/3 传输
强制 IPv4 传输仅使用 A 查询,当要求 curl 仅使用 IPv4 进行传输时,curl 现在仅解析 IPv4 名称。但很大一部分系统在请求 AAAA 地址时会出现问题,因此需要使用此选项来避免 bug
schannel:导入 PFX 时,禁用密钥持久性,使用 Schannel 后端时的一些操作会导致之后磁盘上的剩余文件
添加和使用 Curl_timestrcmp,curl 在比较库中的密钥时使用这个新的恒定时间函数,避免使用时间作为反馈来判断猜测用户名或密码
curl:防止在并行模式下过度排队,命令行工具过于急切地在并行模式下创建和排队等待传输,使得具有数百万传输的命令行很容易使用海量的内存
url 解析器:在不猜测时更好地提取方案
使用 CURLU_URLENCODE 修复不带斜线的解析 URL
url 解析器:更精简,分配更少,URL 解析器现快了几个百分点,且减少了内存分配
url 解析器:拒绝主机名字段中的坏字符
wolfSSL:修复会话管理错误,由于缺少引用计数器,会话 ID 缓存处理可能会触发崩溃。

计划在未来移除以下功能:
支持没有 64 位数据类型的系统
支持 NSS TLS 库

更多信息请参考发行公告

Curl 作者考虑升级其所使用的 C 语言标准

curl 创始人兼核心开发者 Daniel Stenberg 于2022年11月发表博客称正在考虑是否要将 curl 使用的 C 语言标准从 C89 升级到 C99。Daniel 表示观察到许多广受欢迎的 C 语言开源项目正在向前发展,并将所使用的 C 语言标准升级到 C99 或更高版本,例如 Linux、Git 等项目。而且在 curl 的邮件列表中也经常出现关于升级 C 语言标准的讨论,特别是现在已计划在 2023 年春季发布 curl v8,所以从理论上来讲,这可能是进行一些更改的好时机。如果要升级 C 语言标准到 C99,那就要考虑哪些 C99 特性可以改进像 curl 这样的项目。Daniel 表示自己能想到的可能给 curl 代码带来积极影响的部分特性是:
// 注释
__func__预定义标识符
在 <stdbool.h> 中使用布尔类型
指定的结构体初始值设定项
空的宏参数
在 <inttypes.h> 和 <stdint.h> 中使用扩展的整数类型
灵活的数组成员 (zero size arrays)
内联函数
整数常量类型规则
将声明和代码混合
long long 类型和库函数
snprintf() 函数家族
枚举声明中支持尾随逗号
可变参数宏
长度可变的数组

当然,开发者还可以使用许多其他的特性,但问题是他们是否真的需要这些特性。而且对于上面提到的部分特性,Daniel 表示他们已经有了不错的替代方案,其他的特性要么就是无关紧要,要么就是可能会让人分心。因此Daniel认为,如果马上为 curl 项目采用 C99 所有新特性,这会导致重写大部分代码,从而引入错误。此外还有一个问题,如果真的要升级 C 语言标准,是否应该直接升级到 C11,而不是停留在 C99。

在 curl 社区对于升级 C 语言标准的讨论中,没有人能清楚地阐明升级之后能给 curl 项目带来的好处。Daniel 表示他们目前看到的风险是,大家都陷入了与项目非常不相关的讨论和变化中,而这些讨论和变化实际上可能不会使项目取得很大进展。无论是功能还是质量/安全性。Daniel 认为还有很多更好的事情要做,还有更多值得付出的努力来投入精力,这实际上可以改进项目并将其推进。比如改进测试套件、增加测试覆盖率、确保更多代码由模糊器执行。

Daniel 决定从 curl 8 开始,他们将要求编译器支持 64 位数据类型,主要是为了查看它的运行情况。这不是原来的 C89 版本中存在的特性,而是在 C99 中引入的。目前没有不支持此功能的现代编译器。他认为,这也许是可以继续适应和使用特定的 “后 C89 特性” 的方式。通过挑选特定的特性,然后随着时间的推移慢慢适应它们。

最后,Daniel 表示不考虑使用任何其他语言重写 curl。

curl 7 的版本号已迭代到 7.86.0 —— 离发布 7.100.0 只差十多个版本,但 curl 作者 Daniel Stenberg 不希望在次版本号中使用三位数,因为担心这会引发不必要的问题,甚至可能会导致他人用于比较版本的脚本出错。由于 curl 通常每隔 8 周发布一次新版本,如果按照计划的发布节奏,curl 7 的次版本号差不多在两年后就会到达 100。

Daniel 发现明年是 curl 的一个重要周年纪念日,他想到了一个可以避免 "100" 版本号的方案 —— 在 curl 诞生 25 周年当天发布 curl 8。如此一来,既凸显了周年纪念日的地位,又体现了升级主版本号的意义,更是直接避开了 "100" 版本号。可谓是一步到位地实现了 “既要又要还要” 的需求。因此在 2023 年 3 月 20 日,curl 25 岁生日当天,Daniel 将会正式发布 curl 8.0.0。这将会是 curl 23 年来首次升级主版本号。不过正如上文所解释,此次升级主版本号与功能变化无关,也不会进行特别的庆祝。总而言之,这个升级和常规的并无二致,只是重置了次版本号,并升级主版本号。

在常规的 curl 发布周期中,通常是是每隔 8 周在周三发布一次新版本。然而 2023 年 3 月 20 日是星期一。因此curl 8.0.0 的发布时间会有所调整,curl 作者计划在发布 curl 8 之后再调整回常规的发布时间。

最新版本:8.1
v8.1 正式于2023年5月下旬发布,更新内容如下:
该版本只有三个真正的变化,其中包含一个较大的变化和两个较小的变化:
HTTP/2 over proxy:libcurl 现在可以在被告知使用 HTTPS 代理时协商并使用 HTTP/2,而且命令行工具可以使用 [-proxy-http2](<https://curl.se/docs/manpage.html#--proxy-http2>) 选项将其打开。

拒绝解析.onion TLD:当以.onion 结尾的主机名被传递给名称解析器函数时,它们将导致一个错误,不会被解析。其 -w 选项现在可以输出 URL 组件了,变量列表被一系列的新变量所扩展。更多详情可查看此处

最新版本:8.4
v8.4.0 已正式于2023年10月中旬发布,创始人 Daniel Stenberg(社区称号 bagder)并提前一周预告了该版本 —— 修复高危安全漏洞,并称该漏洞可能是很长一段时间以来 curl 遇到的最严重漏洞,同时影响到 libcurl 库和 curl 工具。这个高危漏洞是 SOCKS5 堆溢出漏洞 (heap buffer overflow),该漏洞 (CVE-2023-38545) 导致 curl 在 SOCKS5 代理握手过程中溢出基于堆的缓冲区。有开发者解释称该漏洞出现的场景是输入的域名太长,从而导致内存溢出。当然前提条件是使用了 SOCKS5 代理。两种典型的攻击场景如下:
1.某些程序里内置 libcurl,而允许外部用户指定 socket5 代理以及输入超长的域名,则可以发起攻击
2.用户在使用 curl 或者 libcurl 时,使用了 socket5 代理,并且 http 请求到恶意服务器,并且恶意服务器返回了 http 30x 跳转,把用户访问目标指向一个超长域名从而导致溢出

另一个被评级为 "LOW" 的 CVE-2023-38546 漏洞是通过 none 文件进行 cookie 注入。此漏洞允许攻击者在满足一系列特定条件并将 cookie 放入应用程序当前目录中名为 "none" 的文件的情况下,使用 libcurl 在运行的程序中任意插入 cookie。详情查看此处

curl 默认下载缓冲区为 102400 字节,但如果设置低于每秒 102400 字节,缓冲区大小会自动设置为更小的值。libcurl 下载缓冲区默认为 16KB,应用程序可通过 CURLOPT_BUFFERSIZE 选项设置其大小。受影响版本中,libcurl 对于 Socks 代理过程中解析的主机名长度未正确限制,使用 libcurl 的应用程序在未设置 CURLOPT_BUFFERSIZE 或将其设置小于 65541 时会造成堆缓冲区溢出;由于 curl 工具默认将 CURLOPT_BUFFERSIZE 设置为 100KB,因此除非用户将速率通过 --limit-rate 限制设置为每秒小于 65541 字节,默认不受影响。当用户通过 socks 代理访问攻击者可控的地址时,如果攻击者通过 302 跳转等方式使得用户解析访问大于缓冲区长度的域名,可能造成拒绝服务,针对特定的平台和软件可能造成远程代码执行。

修复方案:不要将 CURLPROXY_SOCKS5_HOSTNAME 代理与 curl 一起使用;不要将代理环境变量设置为 socks5h://。或升级 libcurl 到 8.4.0 或更高版本

最新版本:8.8
v8.8.0 现已于2024年5月下旬正式发布,此版本没有发现任何需要修复的安全漏洞。这是第 257 个版本,包含了 8 项更改、220 个错误修复,共 348 次 commit。
curl_version_info () 提供 librtmp version
file:// 支持目录列表
为 macOS/iOS 提供 AppleIDN 支持
添加 curl_multi_waitfds
mbedTLS 支持 CURLOPT_SSL_CIPHER_LIST
放弃对 NTLM_WB 的支持
实验性的 ECH (Encrypted Client Hello)
为空查询和片段添加 CURLU_GET_EMPTY
更多详情可查看完整公告

最新版本:8.11
v8.11.0 现已于2024年11月上旬正式发布。这是第 262 个版本,包含了 5 项更改、266 个错误修复,共 435 次 commit。具体更新内容如下:
CVE-2024-9681:HSTS 子域覆盖父缓存条目。当 curl 被要求使用 HSTS 时,子域的到期时间可能会覆盖父域的缓存条目,使其比预期更早或更晚结束。
–create-dirs 也适用于 –dump-header
GnuTLS 后端添加了 P12 格式支持
添加了禁用 IPFS 的选项
TLSv1.3 earlydata 支持(使用 GnuTLS)
官方 WebSocket 支持
cmake:document -D 和 env 构建选项
配置:添加对 “unity” 构建的支持
配置:设置 linker flags 以允许 rustls 在 macos 上构建

curl
动态检测 ECH 支持,而不是在构建时检测
支持 --show-headers 和 --remote-header-name
使 --skip-existing 对--parallel 有效

libcurl
conncache:如果捆绑包被删除,请再次查找它
curl.h:删除 CURL/CURLSH/CURLM 类型定义的结构指针
ftp:修复从 stdin 上传时最后写入长度为 0 的问题
hsts:在 max-age 附近正确支持 “隐含 LWS”
lib:删除 hmac/sha256/md5 的函数指针类型转换
mprintf:不要忽略 %o、%x、%X 的长度修饰符
mprintf:将 %o 视为无符号
netrc:将 netrc 文件缓存在内存中
url:重定向时使用相同的凭据
urlapi:规范化 IPv6 地址
......
更多详情可查看完整的发行公告