以 bfg 指令清除含密碼、金鑰的 Git commits

Posted on  Nov 8, 2023  in  Git 版本控制  by  Amo Chen  ‐ 3 min read

眾所周知,版本控制系統會將所有的變更都存起來,因此我們能夠隨意回溯到任一版本,這些變更也包含你不小心提交存有機密資料的檔案,或是帳號密碼等字串。

對於版本控制不熟的使用者來說,可能會以為再提交 1 個已經刪除機敏資料的 commit 就安全了,實則不然,有心人士依然可以透過回溯版本或者在 .git 版本控制系統的資料夾內用工具撈出各種疑似帳號密碼的字串,進而入侵你的系統。

實際上也確實有數起資安事故是由於版本控制系統中含有帳號密碼等資訊所造成。

所以要從清理機敏資料,一定要連版本控制系統內的變動紀錄都要一併清理才安全!

本文將教導如何以 bfg 指令安全地清除含有密碼、金鑰等機敏資料的 commits 。

本文環境

  • macOS
  • BFG Repo-Cleaner
$ brew install bfg

bfg repo-cleaner

BFG Repo-Cleaner 是 1 套專門用來清理 Git 的工具,是 git-filter-branch 的替代工具,速度比起 git-filter-branch 快上 10 到 720 倍,而且使用上更為簡單、直覺,是值得推薦的好工具!

清除含有機密資料的檔案與相關 commits

假設你不小心把機密檔案 secret.json 給 commit 了,例如下列資料夾結構:

.
├── credentials
│   └── secret.json
└── .git

要用 bfg 指令刪除機密檔案的 commits 的話,只要使用 --delete-files 參數並指定路徑與檔案名稱即可(注意,一定要用單引號或雙引號將路徑檔名包起來,因為 bfg 會到 .git 中尋找所有符合的檔名並刪除相關 commit :

$ bfg --delete-files 'credentials/secret.json'

bfg 也支援 * 米字號作為萬用字元,可以一併刪除符合 pattern 的檔案的 commits, 例如下列指令刪除 credentials/ 資料夾底下所有 .json 檔的所有 commits:

$ bfg --delete-files 'credentials/*.json'

bfg 刪除完相關 commit 之後,還需要執行以下指令將 .git 資料夾中相關檔案真正地從檔案系統中刪除,才算完成:

$ git reflog expire --expire=now --all && git gc --prune=now --aggressive

最後將 repo push 回 remote, 蓋掉原本的 .git :

$ git push

怎麼最新的 commit 還是有機密檔案存在?

有人可能會遇到執行 git push 之後,在本地與遠端的 repo 都還是可以看到該機密檔案存在,這是由於 bfg 預設會保護 main/master 分支最新的 commit (也就是 HEAD), 因此不做任何清理,這是由於 main/master 分支最新的 commit 通常跟 production 環境有關, bfg 怕修改之後會影響到 production 環境,所以特別設定保護機制。

要關掉 bfg 預設保護機制的話,只要加上 --no-blob-protection 參數即可,例如:

$ bfg --delete-files 'credentials/*.json' --no-blob-protection

清除含有機密資料的字串與相關 commits

除了刪除機密檔案之外,另 1 種常見的情況是帳號、密碼、 API keys 等字串不小心被 commit 進版本控制系統,這時同樣可以使用 bfg 指令進行清理。

你可以將要清理的帳號、密碼、 API keys 等資料放到 passwords.txt 文字檔內, 1 行 1 個字串,例如:

the_password
123456789

接著,用 --replace-text 參數以及指定以剛剛的 passwords.txt , bfg 會自動找尋所有的 commits 是否含有 passwords.txt 內的字串,並進行清理:

$ bfg --replace-text passwords.txt

被清理的字串會被字串 ***REMOVED*** 取代。

最後同樣執行以下指令清理檔案並 push back:

$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git push

–no-blob-protection 保護

--replace-text 同樣也會有針對 main/master 分支最新的 commit 的保護機制,要關掉保護機制的話,同樣加上 --no-blob-protection 參數即可:

$ bfg --replace-text passwords.txt --no-blob-protection

總結

不小心將機敏資料 commit 是常有之事,為避免機密資料存在版本控制系統之中造成隱患,使用 bfg 等工具進行清理是相當重要的工作。

另外, bfg 不只可以清理機密資料、檔案,也可以用來清理大檔案,避免 Git repo 越長越大,是相當實用的工具!

以上!

Happy Coding!

References

BFG Repo-Cleaner by rtyley

https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!