Curl 存在一個長達 23.9 年的 DOS 漏洞
curl 的作者 Danie 在博客中分享了 curl 持續(xù)了 23.9 年的 DOS 漏洞。
1998 年 10 月, curl 4.9 發(fā)布了,curl 4.9 是第一個帶有 “cookie 引擎” 的版本,可以接收 HTTP cookie、解析、理解并在后續(xù)請求中正確返回 cookie。
當然,當時 curl 的受眾很小,幾個月后 curl 網(wǎng)站才宣布 curl l 4.9 版本的下載量達到了 300 次。而且當時 cookie 也沒有明確的規(guī)范,唯一描述 cookie 如何工作的規(guī)范是 Netscape 網(wǎng)景公司一個非常簡短的文檔,名為 cookie_spec。
在隨后的日子里,IETF(互聯(lián)網(wǎng)工程任務組) 一直在努力創(chuàng)建 cookie 規(guī)范,但大多失敗了。因為 Cookie 有點特別,它們由許多不同的作者、代碼庫和網(wǎng)站實現(xiàn),從根本上改變 “從上而下的規(guī)范” 的工作方式。
直到 2011 年發(fā)布的 Cookie RFC 6265,這是真正意義上的 Cookie 規(guī)范,解釋了 cookie 是什么,以及應該遵守什么。但這也引來了一些問題,RFC 6265 為服務器如何發(fā)送 cookie 提供了一種字段語法,而為客戶端提供了一種截然不同的語法用來接受 cookie。雙重語法導致了兩個問題:
- 很難閱讀規(guī)范,因為很容易陷入其中一種語法,并假設語法對所有用例有效。
- 定義發(fā)送 cookie 的語法沒什么用,因為客戶端才是真正決定如何接收和處理 cookie ?,F(xiàn)有的大型 cookie 解析器(如瀏覽器)在接受的內(nèi)容格式上相當自由,沒有人注意服務器是否遵循 RFC 規(guī)范中的語法。
隨著時間的推移, cookie 的發(fā)展依然緩慢,但 HTTP 規(guī)范在過去的幾十年中已經(jīng)更新了很多次。更重要的是 HTTP 服務器實現(xiàn)已經(jīng)實施了更嚴格的解析策略:如果傳入的 HTTP 請求看起來 “非法” 或格式不正確,HTTP 服務器開始提前拒絕它們?,F(xiàn)在嘗試向一個新的 HTTP 服務器發(fā)送一個包含控制代碼的請求,那么服務器只會拒絕該請求并返回一個 400 響應代碼。
一個 23 年的 Bug
2022 年 6 月末,curl 收到了一份關于 curl 可疑安全問題的報告,這導致 curl 隨后發(fā)布了 CVE-2022-35252。
事實證明,1998 年的 curl cookie 代碼接受包含控制代碼的 cookie??刂拼a可以是名稱或內(nèi)容的一部分,如果用戶啟用 “cookie 引擎”,curl 將存儲這些 cookie ,并在后續(xù)請求中將它們返回。比如:
Set-Cookie: name^a=content^b; domain=.example.com
^a 和 ^b 代表控制碼,字節(jié)碼一和二。由于域可以將 cookie 標記為另一個主機。因此,該 cookie 將包含在對該域內(nèi)所有主機的請求中。當 curl 將這樣的 cookie 發(fā)送到 HTTP 服務器時,它會在傳出請求中包含這樣的標頭字段:
Cookie: name^a=content^b
而默認配置的服務器將響應 400。對于接收這些 cookie 的腳本或應用程序,只要 cookie 繼續(xù)發(fā)送,進一步的請求將被拒絕,形成拒絕服務 DOS 攻擊。
自 4.9 版本以來(curl 項目開發(fā)的第 201),這些易受攻擊的 cookie 代碼就一直存在于 curl 里面,直到 7.85.0 版本(curl 項目開發(fā)的第 8930 天)才得到修復,中間經(jīng)歷了 8729 天(23.9 年)。
當然,據(jù) Daniel 解釋:這些 cookie 代碼當初發(fā)布時沒有問題,并且在用戶使用的大部分時間里也沒有問題。且最新版本的 curl 已經(jīng)完全符合最新的 RFC 6265bis 草案版本的規(guī)定。