持續性威脅:新漏洞將數千個GitHub代碼庫和數百萬用戶置于險境
近日發現的一個新漏洞讓攻擊者可以利用GitHub的代碼庫創建和用戶名重命名操作中的競態條件。該技術可用于執行代碼庫劫持攻擊(劫持流行的代碼庫以分發惡意代碼)。這一發現標志著已第四次發現了一種獨特的方法,有可能繞過GitHub的“流行代碼庫命名空間退役”機制。這個漏洞已報告給了GitHub,已得到修復。
重要發現
? 發現了一個新穎的漏洞,利用在GitHub上創建代碼庫和重命名用戶名的進程之間的競態條件。
? 成功利用該漏洞可以劫持Go、PHP和Swift等語言的4000多個代碼包,以及劫持GitHub操作,從而影響開源社區。值得注意的是,數百個這樣的代碼包已獲得了1000多顆星,數百萬用戶和無數應用程序可能因此受到影響。
? 該漏洞已被負責任地披露給GitHub,GitHub隨后發布了補丁。
什么是代碼庫劫持?
代碼庫劫持是一種攻擊者通過利用邏輯漏洞控制GitHub代碼庫的技術,該漏洞可使重命名的用戶容易受到攻擊。
攻擊者劫持GitHub上一個合法的、常常很流行的命名空間。命名空間是用戶名和代碼庫名稱的組合,比如:example-user/example-repo。
當使用GitHub的“用戶重命名”功能更改原始用戶名時,命名空間可能容易受到代碼庫劫持的攻擊。
用戶名更改過程快速又簡單。一則警告讓你知道舊代碼庫URL的所有流量將被重定向到新代碼庫。

在關于這項功能的文檔中,GitHub提到了重要的影響:
“更改用戶名之后,其他任何人都可以聲稱擁有你的舊用戶名。”
一旦用戶名被重命名,攻擊者可以聲明舊的用戶名,在匹配的代碼庫名稱下打開代碼庫,并劫持命名空間。
“退役”命名空間保護
為了緩解這種潛在的有害行為,GitHub實施了“流行代碼庫命名空間退役”保護措施:任何在用戶帳戶重命名時克隆超過100次的代碼庫都被視為“退役”,無法被其他人使用。
澄清一下:被認為“退役”的是命名空間,意指用戶名和代碼庫名稱這個組合。
比如說,不妨以用戶名“account-takeover-victim”的名為“repo”的代碼庫為例。
這個代碼庫最近被克隆了100次,因此它符合流行代碼庫命名空間退役的條件。

此時,帳戶的所有者決定將用戶名重命名為他所選擇的名稱。
這么做的實際結果是,用戶名“account-takeover-victim”現在可以被任何人聲稱擁有。
然而,一旦這個用戶名的新所有者試圖打開一個名為“repo”的新代碼庫,他們將被阻止,并得到以下消息:

這樣一來,任何人都可以聲稱擁有舊用戶名,但是一旦這個新用戶名所有者試圖用“退役”的名稱創建新的代碼庫,GitHub會阻止這種嘗試。
影響
成功利用漏洞使攻擊者可以接管幾個包管理器中的流行代碼包,包括“Packagist”、“Go”和“Swift”等。我們已經在這些包管理器中發現了超過4000個使用重命名用戶名的包,如果發現新的繞過技術,它們可能受到這種技術的攻擊。在這些面臨險境的代碼包中,數百個已在GitHub上獲得了1000多顆星。
此外,利用這種繞過機制還可能導致流行的GitHub操作被接管,這些操作也可以通過指定GitHub命名空間來使用。對流行的GitHub操作投毒可能會導致重大的供應鏈攻擊,會帶來重大影響。
Aqua最近的研究表明,像谷歌和Lyft這樣的大企業都很容易受到這種形式的攻擊。這凸顯了該漏洞的嚴重性,因為它可能會影響到科技行業的一些大公司,這些公司在接到漏洞通知后迅速降低了風險。

繞過退役命名空間保護的新利用方法
新的利用方法利用了代碼庫創建和用戶名重命名之間潛在的競態條件。Checkmarx SCS部門架構師Elad Rapoport能夠演示通過幾乎同時創建代碼庫和更改用戶名,如何能繞過GitHub檢查。
重現這個漏洞的步驟如下:
1. 受害者擁有命名空間“victim_user/repo”。
2. 受害者將“victim_user”重命名為“renamed_user”。
3. “victim_user/repo”代碼庫現在已經退役。
4. 擁有用戶名“attacker_user”的攻擊者準備了一個命令,該命令創建一個名為“repo”的代碼庫,并幾乎同時將用戶名“attacker_user”重命名為受害者的用戶名“victim_user”。這是使用創建代碼庫的API請求和攔截用戶名更改的重命名請求來完成的。

使用pseudo-exploitation命令的示例
這一發現標志著已第四次發現執行代碼庫劫持的替代方法。Checkmarx在2022年兩次發現并報告了繞過“流行代碼庫命名空間退役”機制的活動,GitHub在這兩次都修復了漏洞。
外部研究人員Joren Vrancken在2022年發現了繞過該機制的第三個漏洞,GitHub也解決并修復了這個漏洞。
用戶能做什么?
我們建議避免使用退役的命名空間以盡量減小攻擊面,并確保代碼中沒有導致GitHub代碼庫容易受到代碼庫劫持攻擊的依賴項。
此外,考慮使用ChainJacking(https://github.com/Checkmarx/chainjacking),這是一個由Checkmarx開發的開源項目,旨在幫助你了解是否有任何Golang直接GitHub依賴項容易受到代碼庫劫持攻擊。
時間線
2023年3月1日——Checkmarx發現了一個繞過GitHub命名空間退役功能的額外漏洞,并向GitHub披露了它。
2023年9月1日——GitHub回復,它已修復了這個漏洞。
結語
在GitHub的代碼庫創建和用戶名重命名操作中發現這個新漏洞突顯了與“流行代碼庫命名空間退役”機制相關的持續風險。
許多GitHub用戶(包括控制流行代碼庫和包的用戶)選擇使用GitHub提供的“用戶重命名”功能。出于這個原因,試圖繞過“流行代碼庫命名空間退役”對于供應鏈攻擊者來說仍然是一個頗有吸引力的攻擊點,有可能造成重大破壞。
此外,值得注意的是,GitHub提供的保護是基于內部指標激活的,并且根本沒有向用戶表明某個特定的命名空間是否受其保護。這可能會使一些代碼庫和包在不知情的情況下處于險境。
我們建議避免使用退役的命名空間,并考慮使用我們的ChainJacking開源項目來識別易受攻擊的包。
我們的團隊繼續努力識別這些漏洞,以確保開源社區的安全。該漏洞已報告給了GitHub。