这是个什么?
Gitleaks 是一个开源 SAST(静态应用安全测试)命令行工具,用于检测 Git 仓库以防止把密码、API 密钥和访问令牌等机密信息硬编码到代码中。
简单来说,就是防止你把密钥公之于众,然后被刷爆。
如何安装
Ubuntu/Debian
APT 似乎没有 Gitleaks 的包,可以选择 下载 对应架构的二进制包,解压后直接运行即可(也可移至 /usr/local/bin 以便全局使用
NixOS
I use NixOS, btw.
Nixpkgs 实在是一个伟大的发明,你只需要运行这行命令:
nix-shell -p gitleaks就可以获得一个临时的,拥有 Gitleaks 软件包的 shell。当然也可以将其加入 systemPackages
Github Action
顺带一提,官方提供了 Action ,可以直接关联仓库并检查(虽然我没用过)
如何使用
gitleaks git . -v该行命令会扫描当前目录下的 git 仓库,并提示可能的泄露 这里我建了一个临时的仓库来实验,并提交了一些commit,然后使用 gitleaks 检查:

虽然 gitleaks 成功检测到了可能的泄露,但此时我们已经提交了很多commit, 一个个 revert 是有些不太现实的。当然,你可以选择直接吊销/轮换密钥。 这里假设密钥和账户强绑定,无法吊销;或者项目曾经是闭源的,没有在意这方面,那就需要强制修改 git 历史了。
强制修改 git 历史的方法
注意请小心谨慎地修改 git 历史,并在
git push后确保在所有设备上拉取一遍以保证同步
git 原生方法
常规修改
如何泄露的影响还算不大,可以使用 Git 内置的交互式变基 (interactive rebase) 来逐个更改提交内容。
例如上图,需要变基到 2e8121e 才能修改之后的 d9df113
git rebase -i 2e8121e
- 我们需要修改
d9df113,因此将第一行的”pick”改成”edit”并保存,开始交互式变基; - 通过编辑器删除泄露的密钥;
- 执行
git add .将更改提交到暂存区,执行git status手动二次确认; - 确定修补完成后,执行
git commit --amend,在这里可以修改 commit 内容,也可以不修改,但必须手动保存一次文件; - 这一轮修复就算成功了,执行
git rebase --continue,git将开始自动合并,直到出现冲突。
处理合并冲突
遇到合并冲突时,使用 git status 查看,并打开冲突的文件:
❯ cat .env<<<<<<< HEAD=======API_KEY=yAxfgL1GnYhk0UYXZdt2eADqnrNXezeKTIME_ZONE=Asia/Shanghai>>>>>>> 72fd120 (feat: 又实现了一个功能)这些格式的意思是:
- 从
<<<<<<< HEAD到=======的部分:当前分支的内容(也就是修改后的) - 从
=======到>>>>>>> 72fd120的部分:旧分支的内容(修改前)
此处需要删除API_KEY,因此将文件修改成:
TIME_ZONE=Asia/Shanghai然后,git add .,git commit --amend,git rebase --continue。如此循环,直到变基全部完成。
最终效果
再次运行 gitleaks git . -v,就可以看到一片绿啦~~

然后 force push 就可以强制修改远端内容:
git push --force --allgit push --force --tagsgit filter-branch 方法
将某个文件从所有历史中移除
先筛选并执行移除:
git filter-branch --force --index-filter \'git rm --cached --ignore-unmatch <文件路径>' \--prune-empty --tag-name-filter cat -- --all再清理备份引用,执行垃圾回收:
rm -rf .git/refs/original/git reflog expire --expire=now --allgit gc --prune=now --aggressive将文件中的某一部分从所有历史中移除
在这里使用sed作为示例,可以让AI编写适合你的替换命令:
git filter-branch --force --tree-filter 'grep -rl "LEAKED_KEY_PART" . | while read -r f; do sed -i "s/LEAKED_KEY_PART/REDACTED/g" "$f"done' --tag-name-filter cat -- --all提示这会在每个提交 checkout 一次,仓库大时将非常慢。 替换模式尽量写具体,避免误伤正常内容。
最后同样是 force push: 然后 force push 就可以强制修改远端内容:
git push --force --allgit push --force --tags