Shai-Hulud
一種會自我擴散的蠕蟲,在安裝受感染的 npm 套件時執行,竊取 npm、GitHub 與雲端權杖,並發布受害者其他套件的受感染版本。多數感染發生在 CI 中。
如何檢查您的建置 →紅隊對藍隊
攻擊者很少鎖定您的公司。他們鎖定的是各地企業都依賴的套件、Action 或建置工具,再一次對所有企業嘗試漏洞利用。他們不需要您的相依套件清單,但您需要。
軟體供應鏈攻擊會入侵產品所依據的某樣東西,例如開源套件、CI/CD 元件或建置系統,而不是直接攻擊產品。現代軟體大多是別人寫的程式碼:其中大部分來自開源套件,而這些套件多數是團隊中沒有人挑選的遞移相依套件。只要入侵一個廣泛使用的元件,就能觸及所有以它為基礎進行建置的組織。
這改變了攻擊者挑選目標的方式。他們不會去研究某一家公司的相依套件,而是挑選影響範圍廣的套件或工具,然後到處利用它,看看誰有回應。
熱門開源套件中的缺陷遭到揭露後,攻擊者會在所有交付該漏洞版本的產品中加以利用,而這通常是沒有人直接挑選的遞移相依套件。
攻擊者接管維護者帳號,或由蠕蟲竊取發布權杖,再發布受信任套件的有毒版本。建置一安裝它就會立即執行,Shai-Hulud npm 蠕蟲就是如此。
貢獻者在開源專案中長期累積信任,然後將惡意程式碼偷偷放進某個版本,再由下游發行版與產品引入,xz utils 後門就是如此。
名稱與熱門套件相近的套件,專門等待打錯字的人。相依性混淆則更進一步:與企業內部套件同名的公開套件,會取而代之被安裝。
GitHub Action 或其他建置工具遭到挾持,所有使用它的管線都會在機密觸手可及的情況下執行攻擊者的程式碼,tj-actions 與 Codecov 就是如此。
建置本身遭到修改,或建置產物在建置與部署之間被調包,因此即使原始碼樹乾淨,產出的版本仍遭入侵,SolarWinds 就是如此。
SolarWinds 是最知名的供應鏈攻擊:惡意程式碼在建置時被植入,並以一般更新的形式交付給客戶。最近的攻擊則轉而鎖定套件登錄庫與 CI 管線,一個遭入侵的套件或 Action 就能觸及所有使用它的建置。由新到舊排列:
一種會自我擴散的蠕蟲,在安裝受感染的 npm 套件時執行,竊取 npm、GitHub 與雲端權杖,並發布受害者其他套件的受感染版本。多數感染發生在 CI 中。
如何檢查您的建置 →CISA 指出,這個熱門 GitHub Action 的所有版本遭入侵長達三天,機密暴露在工作流程記錄中。以標籤參照它的工作流程都執行了攻擊者的程式碼。
Andres Freund 注意到 SSH 登入耗用過多 CPU 後,在 xz 5.6.0 與 5.6.1 版中發現了後門。它是被植入上游專案本身的。
Apache Log4j 2 中的缺陷,能讓掌控某則記錄訊息的攻擊者執行任意程式碼,CVSS 評分為 10.0。對多數團隊而言,困難之處在於找出哪些應用程式包含 log4j-core,而它通常是相依套件的相依套件。
攻擊者竄改了各團隊在 CI 管線中執行的 Bash Uploader 腳本,使其將 CI 環境(包括憑證、權杖與金鑰)傳送到 Codecov 基礎設施以外的伺服器。它從 1 月 31 日起未被察覺地運作,直到 4 月 1 日一位客戶回報為止。
攻擊者長期秘密存取 SolarWinds Orion 的建置流程,將惡意程式碼植入 Orion 2019.4 至 2020.2.1 HF1 版本,而客戶將這些版本當作一般更新安裝。CISA 為此發布了緊急指令。
紅隊對藍隊
以攻擊者的口吻描述每個階段,以及對應的防禦方式。
第 1 階段,共 3 階段
不必了解目標。選定套件,目標自然會浮現。
紅隊
你不需要他們的 lockfile。熱門套件深藏在幾乎所有軟體的遞移相依樹中,而多數團隊說不出自己交付了哪些。公開線索就能縮小範圍:JavaScript bundle 與 HTTP 標頭中的版本、公開儲存庫與容器映像檔。而他們的建置在 lockfile 之外擷取的任何東西,例如 postinstall 腳本下載的二進位檔,或基礎映像檔底下的層,他們的掃描器從來沒看過,所以也沒有人在修補。
藍隊
CRACI 看得到進入每次建置的流量,並記錄建置引入的每個套件與檔案,包括以 lockfile 為基礎的工具會漏掉的隱藏相依套件,涵蓋遞移相依樹的每一層。您的 SBOM 來自實際交付的建置,因此在任何人開始查找之前,您就已經擁有攻擊者從來不需要的那份清單。
建置時 SBOM →紅隊
新的資安公告會明確告訴你哪些版本有漏洞。打造漏洞利用程式、掃描任何有回應的目標,讓掃描結果告訴你對方是誰。你當天就能開始,而他們的團隊還在 Slack 討論串裡問「我們受影響了嗎?」。
藍隊
CRACI 會持續以新的漏洞資料重新評估受監控的 SBOM。建置歷程會顯示哪些建置包含有漏洞的相依套件(無論直接或遞移),讓您知道它交付到了哪裡、持續了多久。
我們受影響了嗎? →第 2 階段,共 3 階段
趁缺陷修補前加以利用,或乾脆跳過缺陷,搭上他們的管線。
紅隊
在對方資安團隊研判工單之前,AI 就能把資安公告與修補差異轉成可用的攻擊。揭露就是你的起跑槍聲,而他們的衝刺規劃排在下週。
紅隊
工作流程信任 @v4 這類標籤,而標籤是可以移動的。入侵一個熱門 GitHub Action,所有使用它的工作流程都會執行你的程式碼,而他們的機密就在觸手可及之處。
藍隊
CRACI 會在建置的 SBOM 中記錄工作流程執行的 GitHub Actions,並固定到實際執行的 commit。當某個 Action 遭入侵時,您可以看到哪些建置執行了惡意程式碼,而不必從標籤猜測。
CI/CD 安全檢查清單 →第 3 階段,共 3 階段
帶走機密,並留下來等待更多。
紅隊
惡意套件版本會在他們的建置中執行安裝腳本,而權杖與雲端憑證就在那裡。CI 執行器通常可以連上整個網際網路,因此在任何人發現套件有問題之前,機密就已經傳到你的伺服器。
藍隊
設為預設拒絕的對外連線政策,讓建置能連到它的套件來源與發布目標,並封鎖其他一切。惡意軟體將您的機密傳送到攻擊者主機的行為會遭到封鎖,即使您是前所未見攻擊的第一個受害者(patient zero)也一樣,而且您會收到違反政策的警示。
對外連線政策 →紅隊
長期運作的自架執行器簡直是送上門的禮物:在工作區或工具快取中埋下東西,等待下一個作業和下一批機密自動送上門。
揭露之後
攻擊者不需要知道您使用了該相依套件。他們到處嘗試漏洞利用,看看誰有回應。您的團隊則需要知道該相依套件交付到了哪裡。差別在於您是否必須四處查找,而且每年要跑的競賽越來越多:請參閱每天發布多少 CVE。
紅隊
藍隊(沒有建置紀錄)
藍隊(使用 CRACI)
沒有任何單一控管措施能阻止所有供應鏈攻擊。將以下措施層層疊加,上述每個階段都會變得更困難。管線方面的詳細內容,請參閱CI/CD 管線安全檢查清單。
攻擊者監控每一則資安公告,並在漏洞揭露當天對所有人嘗試漏洞利用。他們從來不需要您的相依套件清單,但您需要。CRACI 為您的團隊提供這份直接取自建置本身的清單,並關上攻擊者賴以入侵的門:開放的對外連線與共用的執行器。
針對產品所依據的程式碼、工具或服務(例如開源套件、CI/CD 元件或建置系統)發動的攻擊,而非直接攻擊產品本身。一次入侵就能波及所有使用受影響元件的組織。
Shai-Hulud 蠕蟲(自 2025 年起)透過受感染的 npm 套件散播,並竊取 CI 機密。tj-actions/changed-files 遭入侵事件(CVE-2025-30066)挾持了一個熱門 GitHub Action。xz utils 後門(CVE-2024-3094)被偷偷植入上游的壓縮函式庫。Log4Shell(CVE-2021-44228)利用了一個廣泛使用的 Java 記錄函式庫中的缺陷。Codecov 的 Bash Uploader(2021 年)遭竄改,將 CI 憑證傳送到外部伺服器,而 SolarWinds Orion(2020 年)則交付了在建置時被植入的惡意程式碼。
SolarWinds。2020 年,秘密存取 SolarWinds Orion 建置流程的攻擊者將惡意程式碼植入其版本中,客戶則將它當作一般更新安裝。這起事件顯示,乾淨的原始碼樹並不足夠:建置本身也必須值得信任且可驗證。
通常不知道,而且他們也不需要知道。多數攻擊鎖定的是套件,而不是企業:資安公告一發布,攻擊者就會對任何可能執行有漏洞版本的目標嘗試漏洞利用,看看誰有回應。JavaScript bundle 或開源儲存庫中的版本等公開線索,能幫助他們瞄準。不對稱之處在於,您確實需要那份清單:要知道自己是否受影響,您必須知道每次建置交付了什麼,包括它在 lockfile 之外擷取的內容。
沒有任何單一控管措施能阻止所有攻擊。請保留每次建置交付內容的 SBOM,並以新的資安公告持續監控;固定相依套件與 GitHub Actions 的版本;在建置階段封鎖有漏洞的版本;限制 CI 作業能連線的對象;隔離作業並限制其機密;並驗證部署的建置產物就是您建置出來的那些。
提交 lockfile 並在 CI 中依它安裝,在建置不需要時停用安裝腳本(npm 的 --ignore-scripts)。保留每次建置實際安裝了哪些套件版本的紀錄,以便在 Shai-Hulud 這類新一波攻擊公布時快速檢查。限制 CI 作業能連線的對象,讓惡意安裝腳本無法將您的權杖傳送出去,並輪替受感染版本可能接觸到的所有權杖。
在資安演練中,紅隊扮演攻擊者,藍隊負責防禦。本頁採用相同的分工:以攻擊者的口吻描述供應鏈攻擊的每個階段,再由防禦方回應。
已知的可以。已發布 CVE 的惡意版本(例如 xz 後門)會像其他漏洞一樣被標示,政策關卡也能封鎖包含它的建置。CRACI 不分析套件行為,也不評估信譽,因此全新的惡意套件在出現資安公告之前不會被標示。這正是對外連線政策的用途:在預設拒絕的設定下,建置只能連到它需要的主機,因此該套件無法將您的機密傳送出去,即使是前所未見的攻擊也一樣。