掰开揉碎,讲讲这个已存在近24年的CURL漏洞

2024-03-16 12:30

本文主要是介绍掰开揉碎,讲讲这个已存在近24年的CURL漏洞,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

22cbb36cc1528b8282a942fe2aca702b.gif 聚焦源代码安全,网罗国内外最新资讯!

编译:代码卫士

这是一个与cookie、Internet代码和一个CVE有关的故事。故事发生在很久以前,所以搬好小板凳,仔细听好。当然,场景时候curl,它是与我工作有关的互联网传输工具和库。

1f43a4e00fdd4e0c23a5414b88e68548.gif

1998年

1998年,我们推出curl 4.9。在那个年代,少有人听说过或用过curl。距离curl 网站宣布某个新发布的下载量达到300次还有几个月的时间要过。当时,curl从头到尾都是非常小众的存在。

Curl 4.9是第一个具有 “cookie引擎“的发布。当时curl可接受HTTP cookie 并解析,了解这些cookie 并以正确的方式发回给随后的请求,就像浏览器那样。我当时负责的是管理cookie部分的curl代码。

1998年,与cookie如何运作有关的仅有标准是Netscape托管的一个非常简练的文档,名字叫cookie_spec。如有兴趣阅读该文档,可参见文末链接。这份文档实际上记录的并不是非常好,它省略了大量信息,你不得不通过查看其它客户端才能搞清楚。

我当时实现的 cookie 代码就是基于这份文档,浏览器当时似乎就是那样做的。该文档似乎适用于无数服务器实现。人们找到了该特性的良好用途。

4686f8b7332d888c53f69d157503b90b.gif

2000年代

这十年,IETF做出了一些努力创建了cookie标准,但均以失败告终。这些早期cookie标准的作者很可能认为自己可以创建标准,然后全世界就会魔法般地采用这些标准,但事实并非如此。Cookie 在某种程度上是特殊的:它们由如此多的作者、代码库和网站实现,以至于cookie的运作方式被从根本上来讲,以“上面命令“的方式改变了,它们的运作方式很困难,甚至可以说是不可能的。

7bf1d20fc416ca4e30e67f7cc7698c5b.gif

RFC 6265

最终,在2011年,cookie rfc 发布了!这次采用的是与上述方式相反的方法:它主要记录并澄清了cookie实际上是如何被使用的。

我当时也参与在内,提供了一些看法和观点。虽然我并非同意该标准中所述的一切,但相比于之前的状态来说,终于有了一个适当的标准是一个巨大的进步。

33bce40f26e8c1d4328f9ef4e8d3cf44.gif

双重语法

当时并未让我太担心但至此之后一直困扰我的一件事是该标准的编写方式:它提供了一个关于服务器应当如何发送cookie的字段语法,并提供了另外一个关于语法客户端应如何接受cookie的字段语法。

同样的cookie拥有两个语法。

这样做至少存在两个缺点:

1、标准难以阅读,我们很容易落入其中一个语法并假设它适用于自己的用例并意外获得错误的角色描述。

2、定义如何发送cookie的语法实际上并不十分相关,因为客户端才是决定是否应当接受和处理cookie的主体。现有的大量cookie解析器(浏览器)在如何接受方面都十分自由,因此没有人会注意到或者关心服务器是否没有遵信更加严格的标准中的语法。

ce03e55b47007ed42d4acf1fc43dd127.gif

RFC 6265bis

从几年前开始,IETF就一直在修订并更新2011年发布的cookie标准。事情发生了变化,而且一些cookie扩展已得到应用,因此应当被涵盖在标准中。如果我们执行当前管理cookie的代码,那么RFC的旧标准显然不够用,而它的更新版本就是6265bis。

Curl 是最新状态并钰 RFC6265bis 的初稿合规。

以上提及的双重语法问题仍然并未解决,不过当我最近分享关于该标准的选择和想法时遇到了不同寻常的坚决抵制。

我们可以发现,从根本上来讲,cookie的运作方式仍然和1998年时是一样的。当然有一些附加的细微差别和增补,但基本的原则并未改变。而且在cookie标准更新中也将一直如此。

Cookie的其中一个奇特之处在于,它不会像其它web特性那样在源上运作。

751f23bd8a84f71d15f7adecdc27b28e.gif

HTTP 请求隧道

虽然随着时间的流逝,cookie 已发生缓慢改变,但HTTP标准也得到更新并在几十年来更新数次,但可能更加重要的一点是,HTTP服务器实现执行了更加严格的解析策略,如果自由接受,那么很容易导致灾难。严重且反复发生的HTTP请求隧道/走私攻击已向我们证明了这一点。

为对抗此类攻击,并降低其它问题的风险。HTTP服务器开始提前拒绝那些看似“非法“或畸形的HTTP请求。在入门前就拦截阻止。具体而言,请求中的控制代码就是这么做的。当前,如果尝试向包含控制代码的新的HTTP服务器发送请求,那么很有可能该服务器将拒绝该请求并返回响应代码400。这里所说的”控制代码“是值在1到31(排除9)之间的字节。

广为人知的HTTP服务器Apache httpd 自2016年12月发布的2.4.25起,在默认情况下启用该行为。现代的nginx 版本似乎也会这么做,不过我并未调查确切的开始日期。

2a31a1ad23c816cfc10ece74bd037a78.gif

其它主机的cookie

要是今天才开始设计cookie,那么一定会和现在的样子不同。

设置cookie的网站将cookie 发送给客户端。网站会对所发送的cookie设置很多属性。具体而言,当cookie应当被客户端再次发回时,它回设置相匹配的参数。

为cookie设置的其中一个参数是需要匹配客户端发送cookie的域。名为 www.example.com的服务器可为整个 “example.com”域设置cookie,意味着该cookie 随后由客户端发送以及当访问 “second.example.com”时发送。服务器可为“姐妹“网站设置cookie!

5a3ccac1df51c9ebbec2745c51505b2c.gif

最终合二为一

1998年在curl中添加的cookie代码在所接受的内容方面十分自由。虽然多年来得到调整和优化,但该cookie代码仍然发挥着作用,而且和真实的网站兼容。

改动cookie代码的主要动力一直都是确保curl像cookie的其它代理一样以及能和这些代理在野互操作。

4e8b6efa366217c702c53b6227239e75.gif

CVE-2022-35252

2022年6月,我们收到了关于curl安全问题的漏洞报告,也就是后来的CVE-2022-35252。

结果证明,1998年的老旧cookie代码接受包含控制代码的cookie。这些控制代码可能是名称或内容的一部分还好,而如果用户启用了 “cookie 引擎“,则curl将存储这些cookie并将其发送给后续请求。

Curl愿意接受的cookie例子如下:

Set-Cookie: name^a=content^b; domain=.example.com

其中 “^a” 和 “^b” 代表的时控制代码、字节代码1和2。如上所述,由于该域名可为另外一个主机标记cookie,因此该cookie将被包含在该域所有主机的请求中。

当curl将这种cookie 发送给HTTP服务器时,会在出站请求中包括标头字段。

Cookie: name^a=content^b

6e0bc7faf445bd8a0d1880ea57943664.gif

400

默认配置的Apache httpd和其它服务器将返回400。对于接受这些cookie的脚本或应用程序而言,只要cookie还在继续发送,那么进一步的请求就会被拒绝,即造成拒绝服务。

875bd30846d5cd7fbcb03bfde25b8118.gif

标准是怎么说的?

RFC6265中关于客户端的部分即5.2节并不容易解释,而且搞清楚客户端应当摒弃具有控制cookie的cookie要求对文档进行深入研究。实际上,标准中并没有提到“控制代码”或该字节范围。我想我可能只是一个标准的糟糕读者。

0c1b092f804e8e732ed21dd5e4b0f458.gif

浏览器

由于热门浏览器的源代码轻松可获取,因此我们很容易知道它们在干什么。当然,结果我们发现 Chrome 和 Firefox 已经忽视了包含任意字节的进站cookie:

%01-%08 / %0b-%0c / %0e-%1f / %7f

该范围不包括 %09(TAB),%0a/%0d是行尾。

a5b48fe19d56da607bfea053d9110edd.gif

修复方案

Curl的修复方案并不十分了你个人惊讶,只是拒绝包含其中一种或更多被禁的字节值的cookie字段。由于这些字段并未被浏览器接受,因此任何合法网站将其用于任何良好目的的风险非常小,因此我认为这种更改几近零风险。

33fd11c44883ab282d4814c75d074993.gif

漏洞年龄

从4.9版本开始,curl中就已经存在这些易受攻击的代码,也就是说距离修复该漏洞的版本7.85.0已经过去了8729天(23.9年),也就是说我们在项目的第201天引入该漏洞,并在项目的第8930天将其修复。

当代码交付时并没有问题,在大量用户使用它时也并没有问题重重。然而,当 HTTP服务器怀疑是恶意的HTTP请求并拒绝时,问题就来了。因此,代码转变为拒绝服务差不多只是附带损害,是一个遗憾的副作用。

可能在RFC6265发布之时,这个漏洞就存在了。也有可能当第一个广为使用的HTTP服务器开始拒绝这些请求时,这个漏洞就存在了。

e7a26f92c7c7abafac01cbee8d994134.gif

项目记录

一个CVE漏洞在代码中存在了8729天可以说是一个新纪录。不过,它仍然在潜伏期超过8000天的CVE漏洞中排名第四。

最后,感谢Stefan Eissing 深挖Apache的历史详情,感谢Axel Chong提交了CVE-2022-35252提交的漏洞报告。

代码卫士试用地址:https://codesafe.qianxin.com

开源卫士试用地址:https://oss.qianxin.com


推荐阅读

严重的 iOS 漏洞可导致拒绝服务或任意代码执行,苹果已修复

【漏洞预警】Squid缓冲区溢出及拒绝服务漏洞安全预警通告

分析:BIND 服务在处理 DNAME 响应时存在拒绝服务漏洞(CVE-2016-8864)

BT修复拒绝服务协议漏洞

思科TelePresence出现严重漏洞:root访问权限及拒绝服务

原文链接

https://daniel.haxx.se/blog/2022/09/05/a-bug-that-was-23-years-old-or-not/#comments

题图:Pixabay License‍

本文由奇安信编译,不代表奇安信观点。转载请注明“转自奇安信代码卫士 https://codesafe.qianxin.com”。

4fbe3da82592feb613486a605e085de3.jpeg

2cbbc50d7ec68fab519a08a978848ffd.jpeg

奇安信代码卫士 (codesafe)

国内首个专注于软件开发安全的产品线。

   96515e7894eae81d34979c1976ef217f.gif 觉得不错,就点个 “在看” 或 "赞” 吧~

这篇关于掰开揉碎,讲讲这个已存在近24年的CURL漏洞的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/815502

相关文章

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

python通过curl实现访问deepseek的API

《python通过curl实现访问deepseek的API》这篇文章主要为大家详细介绍了python如何通过curl实现访问deepseek的API,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编... API申请和充值下面是deepeek的API网站https://platform.deepsee

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

python 字典d[k]中key不存在的解决方案

《python字典d[k]中key不存在的解决方案》本文主要介绍了在Python中处理字典键不存在时获取默认值的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录defaultdict:处理找不到的键的一个选择特殊方法__missing__有时候为了方便起见,

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal