Skip to content

## ci: 強化 GitHub Actions workflows 安全性(修補 pwn-request 與 secrets 外洩風險) - #80

Merged
ross-nics merged 1 commit into
mainfrom
fix/ci-cd-issue
Jul 24, 2026
Merged

ross-nics merged 1 commit into
mainfrom
fix/ci-cd-issue

Conversation

@ross-nics

Copy link
Copy Markdown
Contributor

摘要

本 PR 針對 CI/CD workflows 進行安全性掃描後的修補,解決一個 High 等級漏洞與數個中低風險問題。

🔴 High:pull_request_target + 可變 ref 的 TOCTOU 攻擊(pwn request)

build.yml 使用 pull_request_target 觸發(帶有完整 secrets 存取權),但 checkout 的是 head.ref(可變的分支名稱)。攻擊情境:

  1. 攻擊者從 fork 開 PR,內容看起來無害
  2. 維護者審核後貼上 safe-to-deploy label
  3. 攻擊者搶在 workflow checkout 之前 push 惡意 commit
  4. 惡意程式碼在可存取 secrets(GCP Workload Identity、GH_PAT)的環境中執行

修正:checkout 改用事件觸發當下不可變的 head.sha,並加上 persist-credentials: false 避免 token 殘留於 git config。

🟠 Medium

  • secrets: inherit 過度授權(build.yml):原本將所有 repo secrets 傳給 deploy job,改為只明確傳遞 GC_WORKLOAD_IDENTITY_PROVIDER
  • 不必要的 GH_PAT(deploy.yml):此 workflow 只透過同一 run 的 workflow_call 呼叫,下載 artifact 使用預設 job token 即可,移除 PAT 減少外洩風險
  • 不必要的 checkout(deploy.yml):deploy job 完全沒用到 repo 檔案,卻 checkout 了不受信任的 PR code,已移除

🟡 Low

  • build.yml / lhci.yml:加上 top-level permissions: contents: read(最小權限)
  • deploy-to-gh-pages.yml:移除永遠為空的 pull_request event 引用(此 workflow 僅由 workflow_dispatch 觸發)

變更檔案

檔案 變更
.github/workflows/build.yml checkout 改用 head.shapersist-credentials: false、top-level permissions、明確傳遞 secrets
.github/workflows/deploy.yml 移除 GH_PAT 與未使用的 checkout、宣告 secrets 介面
.github/workflows/deploy-to-gh-pages.yml 移除死碼(空的 pull_request event 引用)
.github/workflows/lhci.yml 加上 top-level permissions

後續建議(本 PR 未包含)

  • 將所有 actions 從 tag(@v4)pin 到 full commit SHA,並以 Dependabot 管理更新
  • 固定 hugo-version 取代 "latest",確保供應鏈安全與 build 可重現性
  • 確認團隊 safe-to-deploy label 流程:審核最新 commit 後才貼 label,新 commit 進來時移除舊 label
  • GH_PAT 已無其他用途,從 repo secrets 中刪除

測試方式

  • 4 個 workflow 檔案皆通過 YAML / actions schema 驗證
  • 建議合併前先以 workflow_dispatch 手動觸發 build.yml 驗證 build → deploy → comment 全流程

…posure

- build.yml: checkout immutable head.sha instead of mutable head.ref to
  prevent TOCTOU attacks under pull_request_target; disable credential
  persistence; add least-privilege top-level permissions; replace
  'secrets: inherit' with explicit secret passing
- deploy.yml: drop unnecessary GH_PAT for same-run artifact download;
  remove unused checkout of untrusted PR code; declare secrets interface
- deploy-to-gh-pages.yml: remove dead pull_request event refs (workflow
  is workflow_dispatch only)
- lhci.yml: add least-privilege top-level permissions
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@github-actions

Copy link
Copy Markdown

@tony140407 Blue (tony140407) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我的小夥伴說沒問題

@ross-nics
ross-nics merged commit f68477e into main Jul 24, 2026
56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants