請在數小時內發出初步聲明,在能夠證明時盡快提供確認答覆,並在情況有任何變化時發出後續更新。說明您已知道什麼、仍在確認什麼,以及何時會再更新。每一個「未受影響」的說法,都應以攻擊期間您的建置實際安裝的內容為依據,而不是今天的 lockfile。

本文說明該說什麼、何時說,以及以什麼為依據。至於調查本身,也就是如何找出有漏洞的元件是否存在於您的產品中、從何時開始存在,請參閱我們受影響了嗎?。

為什麼客戶問的是您,而不是套件庫

一家小型軟體供應商告訴我們,在一起廣受報導的攻擊發生後那一週,客戶不斷傳簡訊給他:你們的產品安全嗎?我的系統安全嗎?他的客戶處理敏感資料,他的團隊沒有資安專家,而這個問題當天就需要答案。

客戶問的不是某個套件是否遭到入侵。套件庫與研究人員早已說明了這一點。他們問的是您出貨給他們的產品是否包含它,因為您的產品就是他們的曝險。他們也有自己的客戶、稽核人員或主管機關在問他們同樣的問題。在半導體、工業設備與醫療等受監管的供應鏈中,這個問題是合約上的義務,而不是好奇。

如果您的答覆無法查證,他們還會再問一次。沒有任何依據的「我們未受影響」只是一個承諾;「我們檢查了 3 月 24 日至 31 日的每一次版本發布建置,沒有任何一次安裝了受影響的版本」,才是他們可以信賴的陳述。

近期四起攻擊,以及各自引發的問題

正確的答覆取決於攻擊的運作方式,因此光有範本並不夠。以下每一起攻擊,都有一個事實決定了「受影響」對供應商而言代表什麼。

xz Utils 後門(CVE-2024-3094),2024 年 3 月 29 日揭露。 Andres Freund 發現 xz 5.6.0 與 5.6.1 版中有一個後門。版本發布的 tarball 包含不在 Git 儲存庫中的程式碼,並在建置過程中植入後門。NVD 與 Red Hat 依 CVSS 3.1 都給予 10.0 分。它主要影響滾動更新與測試版的發行版:Debian testing、unstable 與 experimental、Fedora Rawhide 與 41、openSUSE Tumbleweed 與 Kali,穩定版則未受影響。它引發的問題是:我們出貨的任何映像檔或裝置是否包含 xz 5.6.0 或 5.6.1?每次建置使用的是哪個基礎映像檔?

Shai-Hulud npm 蠕蟲,自 2025 年 9 月起分波出現。 受感染的套件會在安裝時執行腳本,竊取 npm、GitHub 與雲端憑證,再利用這些憑證發布更多套件的受感染版本。它引發的問題是:是否有任何 CI 作業安裝了受感染的版本?我們的發布權杖是否外洩,使我們成為散播者?我們的 Shai-Hulud 條目列出了每一波攻擊與檢查方法。

PyPI 上的 LiteLLM,2026 年 3 月 24 日。 1.82.7 與 1.82.8 版被直接上傳到 PyPI,其中含有竊取憑證的程式碼,而這些程式碼從未出現在專案的 GitHub 儲存庫中。在 1.82.8 版中,一個 .pth 檔案會在任何 Python 直譯器啟動時執行惡意酬載,而不只是在匯入 LiteLLM 時;它會收集環境變數、SSH 金鑰、雲端憑證與 Kubernetes 機密。HiddenLayer 將這起攻擊與 TeamPCP 連結,該組織同月也攻擊了 Trivy 與 Checkmarx 的工具。LiteLLM 自己的資安公告對最初的入侵途徑提出兩種解釋:它將入侵追溯到其 CI 資安掃描工作流程中的 Trivy 相依套件,同時也表示某位維護者的 PyPI 帳號可能遭到入侵。即使是曝險時間範圍,在同一份公告中也說法不一:一處寫約 40 分鐘,另一處則寫 UTC 10:39 至 16:00。它引發的問題是:是否有任何建置或已出貨的容器包含這些版本?當時那個環境中有哪些機密?

npm 上的 axios,2026 年 3 月 31 日。 攻擊者接管了一位維護者的 npm 帳號,發布了 axios 1.14.1 與 0.30.4,新增了一個相依套件 [email protected],其安裝腳本會植入一個適用於 macOS、Windows 與 Linux 的遠端存取木馬。Datadog 指出時間範圍為 UTC 00:21 至 03:25;Snyk 則記錄這些版本於 UTC 03:29 被移除。它引發的問題是:是否有任何建置在這段時間內解析到這些版本?在這段時間之前提交的 lockfile,對使用它的建置而言答案是「沒有」,但對於未使用 lockfile 就執行 npm install 的建置,它什麼也說明不了。

攻擊生態系受影響版本時間範圍「受影響」對供應商的意義
xz UtilsLinux 發行版5.6.0、5.6.1數週,直到 2024 年 3 月 29 日揭露您在以受影響發行版建置的映像檔或裝置中出貨了它
Shai-Huludnpm每一波數百個套件每一波數小時至數天您用它進行了建置,而您的權杖可能已散播它;您也可能已出貨了它
LiteLLMPyPI1.82.7、1.82.82026 年 3 月 24 日,UTC 10:39 起(結束時間各來源說法不一)您用它進行了建置或出貨了它,而該環境中的機密可能已遭竊取
axiosnpm1.14.1、0.30.42026 年 3 月 31 日,約 UTC 00:21 至 03:25您在這段時間內用它進行了建置;木馬已在建置機器上執行

對於不屬於供應鏈攻擊的重大漏洞,也會出現同樣的問題。PHP2Shell 於 2026 年 10 月遭到利用時,每一個出貨 PHP 的產品,其客戶都會詢問自己的哪些版本含有受影響的 PHP。以下步驟同樣適用,不需修改。

答覆分為三個階段

階段時機您要傳送的內容
初步聲明消息傳出後數小時內您已知道什麼、正在確認什麼、何時會再更新
確認答覆能夠證明時盡快提供,通常是第一天針對指定版本的「未受影響」,或「受影響」及因應方式
後續更新修正版本出貨時、得知新資訊時、結案時同一份通知的修訂版

第一個小時:初步聲明

初步聲明是在事實釐清之前,您所發出的第一份公開聲明。請迅速說出真實的內容。沉默會被各種揣測填滿,而一個完全沒收到您消息的客戶,會以為您根本還沒注意到。

  • 由誰發送、在哪裡發送。 指定一位發送者,透過客戶聯絡您的管道發送,並同步發布在您的資安頁面。一份共用的文字勝過各自臨時的回覆:內容能保持一致,法務也只需審閱一次。
  • 應包含的內容。 您已得知這起攻擊、您正在檢查產品與建置系統、目前已知的資訊、下一次更新的時間,以及聯絡窗口。
  • 不得包含的內容。 在檢查前就說「我們未受影響」、對攻擊者的揣測,或歸咎他人。

範本 1:初步聲明

主旨:[攻擊名稱]:我們的初步聲明

我們已得知 [套件或專案]([受影響版本],於 [日期] 發布)遭到入侵的報告。我們的資安團隊正在檢查 [產品] 的每一個版本以及我們的建置系統,確認是否含有受影響的版本。截至目前,我們 [在已檢查的產品中未發現受影響的版本/尚未完成檢查]。我們將於 [日期與時間、時區] 前提供更新。在此期間如有任何問題,請聯絡 [姓名、資安聯絡信箱]。在檢查完成之前,我們不會對影響範圍進行揣測。

若是簡訊或聊天訊息,兩句話就夠了:

我們已得知 [攻擊名稱] 入侵事件,目前正在檢查 [產品] 的每一個版本與我們的建置。我們將於 [時間] 前提供您確認的答覆。

請在需要用到之前,就先讓法律顧問核准這三份範本。

第一天:以佐證資料確認

可能的結果有兩種,各自需要不同的佐證資料。若要答覆「未受影響」,請收集:

  • 受影響的套件與版本,來自資安公告或研究人員的分析報告
  • 您的產品,以及客戶實際執行的版本
  • 針對每一個版本,產生它的那次建置,以及該次建置安裝內容的記錄,而不是目前的 lockfile
  • 攻擊期間執行的每一次建置,包括從未產生版本的 CI 作業
  • 對於會竊取權杖的蠕蟲,可能執行過惡意程式碼的作業中是否存在任何 CI 機密

我們受影響了嗎?說明了如何確認以上每一項。

您所做的每一個陳述,都必須有可以出示的依據:

陳述您必須能夠出示的內容不足以作為依據的內容
「產品 X 的 Y 版不包含套件 Z」從 Y 版的版本發布建置所記錄的 SBOM對目前儲存庫的掃描
「我們沒有任何建置安裝了遭入侵的版本」該時間範圍內每一次建置的安裝記錄有些作業會略過的 lockfile
「我們的版本發布管線未遭入侵」該時間範圍內的網路與機密使用記錄沒有出現警示
「使用 Y 版的客戶升級後即安全無虞」修正版建置的記錄,以及您已輪替的憑證一筆變更日誌記錄

範本 2:未受影響

主旨:[攻擊名稱]:[產品] 未受影響

我們已完成針對 [套件] 入侵事件([受影響版本])的檢查。[產品] 的下列版本未受影響:[已檢查的產品與版本清單]。我們檢查了 [開始日期] 至 [結束日期] 之間執行的每一次版本發布建置與 CI 建置。本聲明的依據是每次版本發布建置所安裝元件的記錄,而非對我們目前原始碼的掃描。這些建置均未安裝受影響的版本。如您需要佐證資料,我們可以提供您所使用版本的 SBOM,或一份 VEX 聲明。如我們得知任何會改變此評估的資訊,將會通知您。聯絡窗口:[姓名、資安聯絡信箱]。

請針對指定版本說「未受影響」。絕對不要寫「100% 安全」。如果客戶接著要求完整的 SBOM,請參閱回應客戶的 SBOM 請求。

範本 3:受影響,附緩解措施

主旨:[攻擊名稱]:[產品] [x 至 y] 版需採取行動

我們針對 [套件] 入侵事件的檢查發現,[產品] [x 至 y] 版受到影響。第一個受影響的建置產生於 [日期];於 [日期] 發布的 [z] 版已不再包含 [套件版本]。

這代表什麼:[以淺白文字說明風險,例如「這些版本中安裝的某個元件,可能會將其所在系統上的憑證傳送到外部伺服器」]。

您現在應該做什麼:升級至 [產品] [z]。如果無法立即升級,請 [緩解措施,例如封鎖連往所列主機的對外連線]。如果您曾在 [環境] 中使用 [產品] [x 至 y] 版,請輪替該環境可存取的 [憑證或金鑰]。

我們已採取的行動:我們已從建置中移除受影響的版本,以乾淨的相依套件重新建置 [產品],輪替了建置系統所使用的憑證,並 [其他行動]。[我們已依規定通報相關主管機關。]

我們將於 [日期] 前提供下一次更新,如有任何變化將會更早通知。聯絡窗口:[姓名、資安聯絡信箱]。

「受影響」通知也可能是一項法律義務;請參閱下方的通報章節。

VEX 與 CSAF 的角色。 「未受影響」或「已修正」的聲明可以發布為 VEX,讓客戶的掃描工具不再標記該套件。較大型的客戶可能也會期待機器可讀的資安公告;CSAF 是他們之中多數會要求的格式。

後續更新:妥善結案

在修正版本出貨時、調查發現新資訊時發出後續更新,並在結案時發出最後一則通知。每一起事件只保留一份資安公告,並持續修訂,而不是每次都發出一份新的(更新,而非取代)。記錄您在何時告訴了誰什麼內容:下一次稽核或客戶的資安問卷會問到。

還不知道時該怎麼說

「我們還不知道」比一個事後必須撤回的「未受影響」更能建立信任。以下是誠實又不會造成恐慌的說法:

  • 「我們在 [目前已檢查的產品] 中未發現 [套件]。我們仍在檢查 [其餘產品或建置系統],並將於 [時間] 前向您更新。」
  • 「您所使用的版本是在攻擊期間之前建置的。我們正在確認之後沒有任何建置取代了這些版本。」
  • 「我們正在檢查是否有任何建置系統執行了受影響的版本。您已安裝的產品是另一個問題,我們會兩者都回答。」

應避免的說法:

  • 「完全沒有任何影響」
  • 「絕對安全」
  • 「不受任何供應鏈攻擊影響」
  • 「我們的掃描工具什麼都沒找到」

當攻擊成為通報義務

如果您在歐盟銷售具數位元素的產品,Cyber Resilience Act(CRA)的通報義務自 2026 年 9 月 11 日起適用,也就是 ENISA 啟用單一通報平台的那一天。您的產品中出現遭積極利用的漏洞,或發生影響其安全性的重大資安事件時,您必須在得知後 24 小時內發出早期預警、72 小時內提交事件通報,並提交最終報告,透過該平台送交您的協調 CSIRT 與 ENISA。CRA 指南逐步說明這些步驟。

您出貨的某個遭入侵相依套件,或您自己的建置管線遭到入侵,是否符合這些定義,需要由您與法律顧問判斷,而不是由本文判斷。法規對這些用語的定義如下:

  • 「遭積極利用的漏洞」是指「有可靠證據顯示,惡意行為者已在未經系統擁有者許可的情況下,於某系統中利用該漏洞的漏洞」(第 3 條第 42 款)。
  • 資安事件在以下情況屬於重大:「其對具數位元素產品保護敏感或重要資料或功能之可用性、真實性、完整性或機密性的能力,造成或可能造成負面影響」,或「其已導致或可能導致惡意程式碼被引入或執行」於該產品或使用者的系統中(第 14 條第 5 項)。

第 14 條第 8 項另外規定了對使用者的義務:將漏洞或資安事件,以及使用者可採取的任何緩解措施,告知受影響的使用者,並在適當時告知所有使用者,「在適當時以結構化、機器可讀且易於自動處理的格式」提供。範本 3 可以作為履行這項義務的一部分。

其他規範也同樣適用。依據 NIS2,重要實體與關鍵實體須向其 CSIRT 或主管機關通報重大資安事件,而許多客戶合約也有各自的通知條款與期限。

在下一次發生之前做好準備

  • 每一次版本發布建置所安裝內容的記錄,並在產品的支援期間內保存(建置時 SBOM)。
  • 哪些客戶使用哪些版本的清單。
  • 上述三份範本,並已經過法務核准。
  • 針對每一類客戶,指定的發送者與溝通管道。
  • 一個用於發布更新的資安頁面與 security.txt 檔案(協同漏洞揭露)。
  • CI 上的對外連線控管,讓遭入侵的套件無法將機密傳送到建置不需要的主機(GitHub Actions 對外連線政策)。

若資安事件是成百上千地湧入,而不是一次一件,請參閱擴展 PSIRT 規模。

CRACI 的角色

上面的佐證資料表格不斷要求同一樣東西:每一次版本發布建置所安裝內容的記錄。這正是 CRACI 保存的內容。CRACI 在自己的執行器上執行您的 GitHub Actions 建置,並記錄每個作業實際取用的每個套件,包括安裝腳本下載的套件與從快取還原的套件。每一次過去建置的 SBOM 都會保留,因此「是否有任何建置在該時間範圍內安裝了 axios 1.14.1?」可以從建置歷史得到答案,並附上您受影響的期間,最遠可追溯至您的保存期限。

已有公開 CVE 的已知惡意版本(例如 xz 後門),會和其他漏洞一樣被標記,而政策關卡可以封鎖包含它們的建置。CRACI 不會依行為或信譽偵測新的惡意套件。

CRACI 的對外連線政策會封鎖連往建置不需要之主機的連線,限制惡意安裝腳本能向外傳送的內容,即使是前所未見的攻擊也一樣。當客戶要求佐證資料時,您可以將他們所使用版本的 SBOM 匯出為 CycloneDX 或 SPDX 格式並寄送給他們。CRACI 支援 VEX。

從您的建置歷史回答「我們受影響了嗎?」,或進一步了解供應鏈攻擊如何運作。

CRACI 不適用的情況

  • 您需要的是溝通本身的協助。 公關與法律建議是另一回事。
  • 受影響的軟體不是在 CRACI 上建置的。 CRACI 記錄的是在其執行器上執行的 GitHub Actions 建置;其他 CI 系統已列入產品藍圖。
  • 問題涉及的是您沒有建置的廠商產品。 廠商的 SBOM 可以加入 CRACI,但答案的品質取決於廠商 SBOM 的品質。
  • 您需要在任何資安公告出現之前,就攔截全新的惡意套件。 CRACI 會在附有 CVE 的資安公告發布後標記已知的惡意版本;它不會依行為或信譽偵測惡意軟體(因應零時差漏洞)。

常見問題

供應鏈攻擊登上新聞時,我該告訴客戶什麼?

在數小時內發出初步聲明:您已得知這起攻擊、您正在檢查產品與建置、目前已知的資訊,以及何時會再更新。接著在能以建置記錄佐證時,盡快針對指定的產品版本提供確認答覆,並在情況有任何變化時發出後續更新。

初步聲明應該說些什麼?

用一句話說明發生了什麼事、您正在檢查產品與建置系統、目前已發現的內容、下一次更新的時間,以及聯絡窗口。在檢查之前不得說「未受影響」,也不得揣測攻擊者或歸咎任何人。

如何說「我們未受影響」而不過度承諾?

明確列出您檢查的產品與版本、您檢查的建置日期範圍,以及您使用的佐證資料,例如每次版本發布建置所安裝元件的記錄。針對這些版本說「未受影響」,提供 SBOM 或 VEX 聲明,並承諾如有任何變化會再更新。避免使用「100% 安全」或「絕對安全」。

給客戶的「我們受到影響」通知應該包含什麼?

哪些產品與版本受到影響、從何時開始、直到哪個修正版本為止,以淺白文字說明的風險,客戶現在應該做什麼(升級、輪替憑證、封鎖主機),您已經做了什麼,下一次更新的時間,以及聯絡窗口。

「未受影響」的聲明應以哪些佐證資料為依據?

針對客戶執行的每一個版本,提供產生它的那次建置所安裝內容的記錄,而不是今天的 lockfile。再加上攻擊期間執行的每一次建置的記錄;若是竊取憑證的攻擊,還要確認可能執行過惡意程式碼的作業中是否存在機密。

依據 Cyber Resilience Act,我必須通報供應鏈攻擊嗎?

有可能。自 2026 年 9 月 11 日起,在歐盟銷售具數位元素產品的製造商,必須通報遭積極利用的漏洞,以及影響產品安全性的重大資安事件:24 小時內發出早期預警、72 小時內提交事件通報,並提交最終報告。某起攻擊是否符合條件,需要由您與法律顧問判斷。

我們應該多快回覆客戶?

在數小時內發出初步聲明,即使內容只是說明您正在檢查以及何時會再更新也無妨。確認答覆則在您能夠證明時盡快提供。一句快速而誠實的「我們正在檢查」,比一個姍姍來遲的「未受影響」更能建立信任。