<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          LWN:Python的兩個(gè)安全漏洞!

          共 4507字,需瀏覽 10分鐘

           ·

          2021-03-23 19:04

          關(guān)注了就能看到更多這么棒的文章哦~

          A pair of Python vulnerabilities

          By Jake Edge
          February 24, 2021
          DeepL assisted translation
          https://lwn.net/Articles/846847/

          因?yàn)閮蓚€(gè)漏洞(vulnerability)導(dǎo)致了 2 月 19 日快速發(fā)布了 Python 3.9.2 和 3.8.8,在其之前幾天就發(fā)布了 3.7.10 和 3.6.13 的純?cè)创a release。這些漏洞可能會(huì)對(duì)一些 Python 用戶和使用場(chǎng)景造成問題,其中一個(gè)可能會(huì)導(dǎo)致遠(yuǎn)程代碼執(zhí)行(remote code execution)。另一個(gè)可以說并不完全是 Python 標(biāo)準(zhǔn)庫(kù)自己的缺陷,畢竟它只是也是遵循了一個(gè)舊標(biāo)準(zhǔn),但它確實(shí)可能會(huì)導(dǎo)致web cache poisoning 攻擊。

          Overflowing

          所解決的第一個(gè)漏洞是CVE-2021-3177,這是 1 月 16日提交的bug報(bào)告中發(fā)現(xiàn)的一個(gè)緩沖區(qū)溢出問題。當(dāng)使用為 Python 為了提供兼容 C 的數(shù)據(jù)類型的 ctypes module 來將浮點(diǎn)數(shù)轉(zhuǎn)換為非指數(shù)形式近似值的字符串時(shí),就可能會(huì)發(fā)生問題。使用一個(gè)非常大的數(shù)字將使 python 解釋器崩潰,正如下面這個(gè)示例所示 (這是根據(jù) bug 報(bào)告中的想法改造出的示例):

          >>> from ctypes import *
          >>> c_double.from_param(1e30)
          <cparam 'd' (1000000000000000019884624838656.000000)>
          >>> c_double.from_param(1e300)
          *** buffer overflow detected ***: terminated
          Aborted

          正如錯(cuò)誤信息所示,這里出現(xiàn)了緩沖區(qū)溢出問題,具體來說是因?yàn)?nbsp;sprintf() 這個(gè) C 函數(shù)會(huì)將格式化過的字符串 "print" 到緩沖區(qū)(buffer)里,如果緩沖區(qū)足夠大,那么就沒問題。sprintf() 導(dǎo)致緩沖區(qū)溢出的問題可以追溯到 50 多年前就有出現(xiàn)過了,但人們可以使用更安全的替代函數(shù)。bug 報(bào)告者 Jordy Zomer 建議使用 snprintf(),它需要一個(gè) size 參數(shù),不會(huì)向字符串中寫入超過 size-1 數(shù)量的字符,最后還有一個(gè) NUL 終止符。

          報(bào)告里面也指出了導(dǎo)致出錯(cuò)的代碼:

          case 'd':
          sprintf(buffer, "<cparam '%c' (%f)>",
          self->tag, self->value.d);
          break;

          這里的 "%f" 就是指要將 float 值轉(zhuǎn)成字符串,所以如果傳遞一個(gè)非常大的數(shù)字(比如說 1e300)進(jìn)來,就會(huì)創(chuàng)建出一個(gè)非常長(zhǎng)的字符串,導(dǎo)致這個(gè) 256 字節(jié)的、基于 stack 的緩沖區(qū)發(fā)生溢出。如果某個(gè)程序?qū)τ脩籼峁┑臄?shù)據(jù)來進(jìn)行這種格式轉(zhuǎn)換,就可能導(dǎo)致執(zhí)行惡意代碼,因?yàn)楣粽呖梢詫?duì)溢出寫入 stack 的數(shù)據(jù)有部分控制能力。如果這個(gè)輸入數(shù)據(jù)是從網(wǎng)絡(luò)上來的,那么當(dāng)然就可能產(chǎn)生遠(yuǎn)程代碼執(zhí)行攻擊(remote code execution)。然而,在 python-dev 郵件列表上,Stephen J. Turnbull 對(duì)這個(gè) bug 是否真的那么容易利用表示懷疑,他認(rèn)為沒有必要急于發(fā)布新版本來解決這個(gè)問題。

          在這個(gè) bug 被報(bào)告出來之后,Benjamin Peterson 很快就在多個(gè) Python branch 上都進(jìn)行了修復(fù)。不過他沒有使用 snprintf() 來修復(fù),而是使用了 PyFloat_FromDouble() 和 PyUnicode_FromFormat() 兩者組合來解決這個(gè)具體問題。在 1 月 18 日的 patch 中可以看到,他還將 ctypes module 中其他對(duì) sprintf() 的調(diào)用也改為使用 PyUnicode_FromFormat() 。PyUnicode_FromFormat()不需要一來一個(gè) buffer(緩沖區(qū)),而是會(huì)算出要生成的字符串的大小,分配出來,然后將其返回。

          正如 Python bug-tracking page 所顯示的,這個(gè)問題在兩天內(nèi)就被修復(fù)了。大約一個(gè)月后,目前仍然得到支持的四個(gè) Python 版本全都發(fā)布了新的 release。雖然 Python 2.7 已經(jīng)沒有 python 核心開發(fā)者的支持了,但一些發(fā)行版仍然會(huì)針對(duì)安全問題來提供更新。這次這個(gè)問題只出現(xiàn)在 Python 3.x 中,所以沒有必要 backport 這個(gè) fix。【更新:正如 Moritz Muehlenhoff 在郵件中所指出的,Python 2.7 實(shí)際上也受到了這個(gè) bug 的影響。他指出 Debian 10("Buster") 上的 python2 也受到了影響,并且已經(jīng)更新。此外,F(xiàn)edora 也正在對(duì) python2.7 包進(jìn)行修復(fù)。】

          Poisoning the web cache

          新版本所解決的第二個(gè)漏洞是 CVE-2021-23336,這是由于對(duì) URL query 參數(shù)的分隔符的不同解釋而導(dǎo)致的對(duì) Web cache 的污染攻擊。舊版的 HTML4 規(guī)范允許用";" 和 "&" 來分隔查詢參數(shù),但 HTML5 只允許使用后者。標(biāo)準(zhǔn)庫(kù)中的 urllib.parse 模塊遵循了舊的規(guī)范,但這可能會(huì)導(dǎo)致 web cache 出問題。

          根據(jù) bug 跟蹤頁(yè)面,該問題在 2020 年 10 月就被報(bào)告給 Python 安全響應(yīng)團(tuán)隊(duì)(PSRT,Python security response team),但在 1 月 18 日的一篇 Snyk blog文章 以及 1 月 19 日的 bug 報(bào)告導(dǎo)致該問題被公開,都是來源于 Adam Goldschmidt。

          這篇 blog 內(nèi)容很豐富,介紹了 Web 緩存污染的問題,以及某些 Python Web 框架如何成為了這類攻擊的對(duì)象。基本思路是,人們出于性能考慮,經(jīng)常使用 Squid 等工具對(duì) Web query 進(jìn)行緩存。緩存條目的索引 key 通常是使用 URL 中的一部分,如果一個(gè)新的 request 與這個(gè)索引 key 相匹配了,則會(huì)直接將 cache 中的版本返回回去,而不是從 host 再次請(qǐng)求獲取。這樣既可以減少響應(yīng)時(shí)間,一方面因?yàn)闆]有到遠(yuǎn)程主機(jī)去繞一圈,從而減少了網(wǎng)絡(luò)引入的耗時(shí),另一方面因?yàn)闆]有在遠(yuǎn)程 host 上進(jìn)行任何處理,所以就不存在應(yīng)用層的延遲。

          web 緩存污染有若干種類,但這次影響 Python 的是主要因?yàn)?cache 和 web 這兩臺(tái)服務(wù)器對(duì) URL 的解釋不同。基于 Python 的 web 應(yīng)用如果使用 urllib.parse.parse_qsl(),則會(huì)把分號(hào)和 ampersand 符號(hào)(&)都看成是查詢參數(shù)的分隔符,但 cache server 通常不會(huì)這樣做。此外,有一些查詢參數(shù)通常是不會(huì)用來作為 cache key 的(比如 utm_content 和其他 utm_*參數(shù))。這使得攻擊者可以進(jìn)行這樣的 query:

          https://example.com/search/?q=common_term&utm_content=s;q=malicious_term

          web cache 認(rèn)為這個(gè)查詢有兩個(gè)參數(shù),其中一個(gè)不會(huì)用在 key 中,但是在 web server 里運(yùn)行的 Python 應(yīng)用會(huì)將其看做是有三個(gè)參數(shù),第二個(gè) q 會(huì)將第一個(gè)參數(shù)的值給覆蓋掉。這樣一來 web cache 中本來指向 "common_term" 的 cache 會(huì)被引向 "malicious_term"。在 cache 內(nèi)容過期(expire)之前,用戶根本無法訪問到他們所期待訪問的東西,取到的是別人希望它看到的。這當(dāng)然會(huì)事實(shí)上導(dǎo)致各種令人不快、令人困惑的攻擊,會(huì)有潛在風(fēng)險(xiǎn)。

          最明顯的解決方案就是讓 Web 應(yīng)用停止將分號(hào)當(dāng)做分隔符,但直到 2 月 14 日合入的改動(dòng)(并在此后不久正式包含在 release 版本中)才真正在 urllib.parse 中改成了這樣。之前的版本都無法控制了。這個(gè) patch 將默認(rèn)行為改為只允許用分號(hào)來分隔查詢參數(shù)。它還為 parse_qsl() (以及相關(guān)的 parse_qs()) 添加了一個(gè)新的、可選的 separator 作為參數(shù),允許開發(fā)者選擇使用其他分隔符,比如可以是分號(hào)。但需要注意的是,無法使用超過一種分隔符,所以無法再回到現(xiàn)有的行為(接受兩個(gè)查詢分隔符)了。

          顯然,這個(gè)改動(dòng)本身是非常簡(jiǎn)單直接的。這個(gè) patch 中大部分內(nèi)容都在修改文檔和測(cè)試集(這里也有)。不過與緩沖區(qū)溢出那個(gè)問題不同的是,這個(gè) bug 也影響到了 Python 2.7,Red Hat 的 bug tracking 頁(yè)面上就指出了這一點(diǎn)。

          可以說,這里并不完全是 Python 的錯(cuò)。正如 bug report中提到的,W3C 確實(shí)在 HTML4 規(guī)范中建議使用分號(hào),不過是在附錄中,而不是在此規(guī)范的主體部分。也有一些人認(rèn)為改變默認(rèn)值(并取消處理兩種分隔符的功能)的方法不好,但 urllib 維護(hù)者 Senthil Kumaran 決定最好在 urllib 中進(jìn)行修復(fù),并按照這種避免讓 Web proxy 感到混亂的方式來 fix。

          這兩個(gè) bug 并沒有什么特別值得注意的地方,但它們確實(shí)給大家展示了一下 Python security process(安全流程)。緩沖區(qū)溢出的問題解決得相當(dāng)快,但 web cache poisoning 的問題花了相當(dāng)長(zhǎng)的時(shí)間來解決。目前還不完全清楚在 PSRT report 和公開披露這個(gè) bug 之間的三個(gè)月里發(fā)生了什么。不過在那之后,開發(fā)人員的動(dòng)作相當(dāng)迅速。除此之外,了解一下正在出現(xiàn)的漏洞種類總是會(huì)有用的,至少,它可以幫助人們留意其他類似領(lǐng)域中的類似問題。

          全文完
          LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。

          歡迎分享、轉(zhuǎn)載及基于現(xiàn)有協(xié)議再創(chuàng)作~

          長(zhǎng)按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開源社區(qū)的各種新近言論~




          瀏覽 74
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91一区二区三 | 国产精品无码7777777 | 99成人免费视频 | 逼特逼视频最新网址 | 黄色美女大奶被操日韩 |