2026 年每日通報的 CVE 數量比前一年多 131%。

CI/CD 資安

以對外連線政策阻止 GitHub Actions 的資料外洩

CI 作業持有機密,並執行一分鐘前才下載的程式碼:actions、套件及其安裝腳本。只要其中任何程式碼是惡意的,竊取機密最簡單的方法就是把它們傳送到某台伺服器。對外連線(egress)政策決定作業可以連到哪些伺服器,並封鎖其餘所有連線。

更新日期

機密如何從 CI 作業外洩

作業可以存取儲存庫權杖、傳入的機密,以及它所取得的任何雲端憑證。在作業中執行的程式碼都能讀取這些資訊,接著可以透過幾種方式將它們帶出去:

  • 透過網路。向攻擊者控制的伺服器發出請求。這正是對外連線政策所封閉的管道。
  • 透過記錄。將機密(通常經過編碼)輸出到作業記錄中。2025 年 3 月,CISA 報告指出,遭入侵的 tj-actions/changed-files action 就是以這種方式洩漏機密。
  • 透過輸出。建置產物、快取,或以作業權杖推送的 commit。

這段程式碼不一定是惡意套件。工作流程中的 AI 代理可能被隱藏在 issue 或 pull request 中的提示詞注入操控,進而利用相同的管道。

對外連線政策的作用

多數作業只需要連到一小份目的地清單:套件庫、容器映像檔庫、原始碼主機與少數服務。對外連線政策允許這份清單,並封鎖其他所有連線。採用預設拒絕的政策時,連往未知主機的請求會失敗,機密也就留在作業之中。

What happens when malware in a build tries to send your secrets out Left, a runner that allows all outbound traffic: the build reaches its package registry and publishes its output, then a malicious install hook sends the build's secrets to an attacker's server, and they arrive. Right, CRACI with a default-deny egress policy: the registry and publish connections are allowed, the connection to the attacker's server is blocked at the policy, and an alert is sent. The policy allows only what the build needs, so it works even against an attack nobody has seen before. Any outbound allowed build job holds your tokens and keys malicious install hook runs no egress policy package registry publish output attacker server allowed allowed secrets sent to the attacker CRACI default-deny egress policy build job on CRACI holds your tokens and keys malicious install hook runs egress policy: only what the build needs package registry publish output attacker server allowed allowed blocked blocked, and you get an alert
The policy allows only what the build needs, instead of looking for known-bad hosts, so it stops a new attack the first time it runs.

但它並不能封閉所有管道:

  • 它無法阻止機密被輸出到記錄中。請將記錄設為不公開,並將 actions 釘選到 commit SHA。
  • 您允許的目的地仍可能被用來帶出資料,因此請讓允許清單維持精簡。
  • 它無法告訴您哪些套件是惡意的。那是套件篩檢與 SBOM 的工作。

三種執行方式

  • 執行器上的代理程式。StepSecurity Harden-Runner 會被加為作業的第一個步驟。它將每個連線對應到發出連線的步驟,在稽核模式下建立基準,並封鎖連往允許清單以外目的地的對外連線。
  • 內建政策的執行器。CRACI 由執行器本身執行政策。其他執行器供應商也提供網路管控,例如 Depot 的 Linux 執行器提供對外連線過濾,Namespace 則提供封鎖型或建議型的對外連線政策。
  • 您自己的網路。將自架執行器置於由您自行設定與維護的防火牆或代理伺服器之後。

在不讓建置失敗的前提下導入

  1. 觀察。在數次執行中記錄作業建立的每個連線。
  2. 允許。依據作業實際需要的內容建立允許清單。
  3. 封鎖。切換為預設拒絕,並留意違規情形。
  4. 檢視。將每個新的違規視為缺漏的來源或一起資安事件。

CRACI 的做法

在 CRACI 上,對外連線政策是執行器的一部分。它會在作業開始前完成驗證,拒絕未知的欄位,並採失效即封鎖(fail closed)。內建的預設組態涵蓋常見的套件來源,其餘則透過自訂來源與連線補上。作業追蹤記錄會列出每個連線,每個遭封鎖的連線都會以違規形式連同原因列出。由於代理伺服器具備套件感知能力,同一份記錄也會成為該作業的 SBOM。API 會回傳 SBOM、網路追蹤記錄與來源證明(provenance)。

CRACI 目前還沒有專用的稽核模式,此功能已列入產品藍圖。沒有網路政策時,作業的流量會被允許並記錄在追蹤記錄中,因此您可以在強制執行前先看到政策需要涵蓋哪些內容。CRACI 在 Linux 上執行 GitHub Actions 作業。請參閱CI/CD 資安工具比較與CRACI 與 StepSecurity 比較。

CI 的對外連線政策:常見問題

什麼是 CI 中的對外連線(egress)政策?

一組規範 CI 作業可建立哪些對外網路連線的規則。作業可以連到它需要的套件庫與服務,其他所有目的地都會被封鎖。

對外連線政策能阻止 tj-actions 遭入侵事件嗎?

單靠它無法阻止。根據 CISA 的報告,該事件中的機密是透過工作流程記錄外洩,而不是傳送到外部伺服器。對外連線政策能封閉網路管道;將 actions 釘選到 commit SHA 並將記錄設為不公開,則能處理記錄管道。

封鎖對外連線會讓建置失敗嗎?

如果政策漏掉了建置需要的來源,就可能會。請先記錄作業連線的目的地,據此建立允許清單,然後再封鎖。在 CRACI 上,內建的預設組態涵蓋常見的套件來源,遭封鎖的連線會連同原因顯示在作業追蹤記錄中。

可以在 GitHub 託管執行器上使用對外連線政策嗎?

可以,只要在作業中加入代理程式,例如 StepSecurity Harden-Runner。或者,將作業移到本身就會執行政策的執行器,例如 CRACI。

讓一個作業受對外連線政策保護

在 CRACI 上執行一個工作流程,查看它建立的每個連線、允許清單需要納入的主機,以及它所取用內容的 SBOM。

預約示範