適用對象:個人開發、小規模維運中使用 Git,並且擔心『會不會不小心把 API 金鑰提交上去』的人。本文不講攻擊方的手法,只講阻止金鑰從自己的儲存庫流出的機制。
本站的視角:光靠 .gitignore 守不住金鑰
常聽到有人說『我把 .env 放進 .gitignore 了所以沒問題』,但這是有漏洞的。.gitignore 只是不把新檔案納入追蹤而已,對已經提交的金鑰、趕時間用 git add -f 強制加入的金鑰、以及像 .env.local.bak 這種意料之外的檔名都抓不住。gitignore 只堵住了『入口的一部分』。真正去看提交內容、檢出『看起來像金鑰的字串』的機制——也就是檢測器——還得另外配一個。這正是 gitleaks 的職責。
為什麼要在『提交前』攔住
金鑰之所以危險,是因為 Git 會永久保留歷史。即使從最新檔案裡刪掉,過去的提交裡還留著。而且在 push 的那一刻,那段歷史就會被複製到他人的本地、伺服器以及 CI 的記錄裡。
也就是說,金鑰防護的正道不是洩漏後的回收,而是洩漏前的阻止。這跟『別把金鑰忘在公開目錄裡』的盤點(→ webroot 的盤點)是同一個思路,只是把它搬到了程式碼的世界。
攔截點在哪裡
在金鑰從程式碼流向外界的路徑上,可以設兩道攔截點。本地提交時,以及被共享之前(CI)。
程式碼裡的金鑰
API 金鑰、私鑰、token
門 1:pre-commit
提交時在本地檢出並中斷
門 2:CI / cron
push 後在合併/部署前檢出
公開・共享
到這一步就要按已洩漏處理
gitleaks 的整合方式
先掃描現有歷史
gitleaks detect 掃描一次。把過去提交裡潛伏的金鑰翻出來,是第一件要做的事。這裡找到的東西,正如後文所述以撤銷為前提。用 pre-commit 掛鉤建好門 1
gitleaks protect --staged,當場中斷含金鑰的提交。加到 pre-commit 框架(.pre-commit-config.yaml)裡,團隊和本地就都會跑同一套檢查。用 CI / cron 建好門 2
gitleaks detect 抓住漏網之魚(→ 跟相依套件稽核一樣,是機器監控的思路)。誤報用 .gitleaks.toml 調整
.gitleaks.toml 來調整。不是『讓它閉嘴』,而是『記錄下為什麼它是安全的』才是正確的維運——沒有依據的排除會成為下一次事故的溫床。檢出後先『撤銷』,改寫歷史在後
一旦發現已被提交、push 的金鑰,最優先的是撤銷並重新簽發(輪換)那個金鑰/token。用 git filter-repo 等從歷史裡刪掉固然重要,但那只是為了『不再擴大』的善後處理。要認為已經流到公開儲存庫、fork、CI 記錄、他人 clone 裡的金鑰無法回收,請先作廢再去清理歷史。順序反了的話,你刪的時候它已經被人用了。
只靠 .gitignore
- 只能防住新的追蹤
- 已經提交的金鑰直接放行
- 對
git add -f或意料之外的檔名無能為力 - 無法驗證『我以為沒放進去』
gitleaks(檢出+撤銷維運)
- 實際檢查工作樹和歷史的內容
- 用 pre-commit 和 CI 兩道攔截
- 檢出後把直到撤銷的步驟流程化
- 誤報記錄依據後再排除
本站是怎麼做的
本站從根本上以金鑰一概不放進 Git 的設計為基礎——連線資訊和 API 金鑰只放在伺服器上受保護的設定裡(權限收緊的環境檔),既不在儲存庫裡、也不在交接資料裡留明文(→ 不把金鑰放進 git/自架 Git vs GitHub)。在此之上,再以人一定會犯錯為前提疊加檢測器。用設計保證『不放進去』,用 gitleaks 這類掃描抓住『還是放進去了』——這兩層,就是本站面對金鑰洩漏的防守。金鑰處理的原則本身,跟 .env 與金鑰資訊 以及 安全保存密碼 也是一脈相承的。
接下來閱讀
FAQ
Qgitleaks 是什麼?
它是一款免費工具,會掃描 Git 儲存庫的工作樹和提交歷史,檢出是否有 API 金鑰、私鑰、token 等金鑰被提交。它透過正規表示式規則和字串的熵(隨機度)來找出『看起來像金鑰的字串』,可以整合進 pre-commit 掛鉤或 CI 進行自動檢查。
Q只要寫進 .gitignore 就能守住金鑰嗎?
不夠。.gitignore 只是『不把新檔案納入追蹤』而已,對已經提交的金鑰、或用 git add -f 強制加入的金鑰無能為力。gitignore 只能擋住一部分事故,所以要把像 gitleaks 這樣的檢測器放進 pre-commit 和 CI 做雙重保險。
Q不小心把金鑰提交並 push 了怎麼辦?
要把那個金鑰當作『已經洩漏』來處理。最優先的不是改寫歷史,而是撤銷並輪換(重新簽發)洩漏的金鑰/token。要認為一旦進入公開儲存庫或記錄的金鑰就再也收不回來,先把它作廢,之後再清理歷史並做防復發(引入 gitleaks)。