Betterleaks Git 密钥扫描实战:如何快速挖掘提交历史与暂存区中的泄漏凭证
【免费下载链接】betterleaksFind leaked secrets everywhere.项目地址: https://gitcode.com/gh_mirrors/be/betterleaks
Betterleaks是一款可配置、速度快且检测彻底的密钥泄漏扫描器(secret scanner),由 Gitleaks 原班团队维护。它的git扫描模式可以深入 Git 提交历史、暂存区(staged)与工作区差异,帮助你在密钥被"删掉"之后依然把它们找出来——因为 Git 历史里从未真正遗忘任何一行内容。
为什么 Git 历史是密钥泄漏的重灾区
删掉配置、从分支中移除 Token、甚至git reset重做提交——这些操作都无法抹去历史对象。密钥只要曾经被 commit 过,就会一直躺在仓库的.git/objects里等待被挖出。
| 泄漏场景 | 传统做法 | Betterleaks 方案 |
|---|---|---|
| Token 提交后被删除 | 重写历史(危险且繁琐) | 一次扫描历史,精确定位引入密钥的提交 |
| 密钥写在 commit message 里 | 人工翻记录 | --include=commit-messages自动覆盖 |
| amend / rebase 后"丢失"的提交 | 手动翻 reflog | --include=reflogs恢复覆盖 |
| 密钥即将随 commit 推送 | 事后补救 | --staged暂存区拦截 + pre-commit 钩子 |
| 团队仓库批量防护 | 无 | 服务端--pre-receive钩子直接拒绝推送 |
默认规则集内置了几百条厂商规则(GitHub PAT、AWS、OpenAI、Stripe 等),见 config/betterleaks.toml。
快速上手:扫描完整提交历史
安装 Betterleaks 后,最简单的一条命令就是扫描当前仓库的全部历史:
betterleaks git .它会并行遍历每一次提交的文件补丁(patch),用内置的正则规则 + 关键词预过滤(Aho-Corasick)高速匹配。报告里会给出密钥所在的确切提交 SHA、文件路径与行号,并附带作者与时间信息,让你能直接回答"是谁、在哪个提交里泄漏的"。
常用增强选项:
# 只扫最近 90 天、且只看 src/ 目录下的补丁 betterleaks git . --log-opts="--all --since='90 days ago' -- src/" # 同时扫描提交说明文字(commit message 里贴 Token 的意外并不罕见) betterleaks git . --include=commit-messages # 同时扫 tag 注解消息与本地 reflog(覆盖 amend/reset/rebase 丢弃的提交) betterleaks git . --include=commit-messages,tag-messages,reflogs # 大仓库提高检测并发 betterleaks git . -j 8💡
--include=reflogs是一个容易被忽略的利器:它能把被git amend、git reset或git rebase抛弃的提交重新纳入扫描范围,见 docs/scanning.md 中 reflogs 一节。
暂存区扫描:在 commit 发生前拦截密钥
这是本文的重点场景——把扫描左移到提交之前。
# 只扫描暂存区(index 相对 HEAD 的新增行) betterleaks git --staged--staged模式只读取暂存的新增内容,不触碰历史,速度极快,且默认关闭网络验证,完全适合放在本地钩子里。官方仓库自带了一个现成的 pre-commit 钩子脚本 scripts/pre-commit.py,它内部就是执行betterleaks git --staged --redact:
- 检测到泄漏 → 非零退出码 →本次 commit 被 Git 直接拒绝;
--redact让终端输出中的密钥被遮蔽,避免二次泄漏到日志;- 钩子受
git config hooks.betterleaks开关控制,默认启用。
类似的还有--unstaged:扫描已跟踪文件中尚未暂存的新增行(不包含 untracked 文件)。两者的定位差异:
| 命令 | 扫描范围 | 典型用途 |
|---|---|---|
betterleaks git --staged | 暂存区新增行(相对 HEAD) | pre-commit 钩子,提交前拦截 |
betterleaks git --unstaged | 工作区新增行(相对 index) | 写代码时的实时自查 |
betterleaks git . | 全部提交历史 | 接手新仓库 / 安全审计 |
betterleaks fs . | 文件系统完整文件(含未跟踪文件) | 全量兜底扫描 |
从本地到团队:把防护做成流水线
1. 提交前(pre-commit)
将 scripts/pre-commit.py 放入.git/hooks/pre-commit并赋予可执行权限即可。需要临时跳过时执行:
git config hooks.betterleaks false2. 推送时(pre-receive,服务端)
在(bare)服务端仓库中部署hooks/pre-receive,只扫描本次推送新增的提交(<old>..<new>区间),发现泄漏就以非零码让 Git 拒绝整个 push,并可通过--pre-receive-error-message向推送者打印自定义提示。相关实现位于 sources/pre_receive.go。
3. 验证密钥是否仍然有效
扫描只回答"哪里出现了密钥",加上-v还能回答"它还能用吗":
# 验证检测到的凭证是否仍然有效 betterleaks git . -v # 验证 + 分析身份与权限(该密钥属于谁、能做什么) betterleaks git . -a分析会解析出账号身份、权限范围(如 GitHub Token 的 scopes)与严重度评分,帮助你在众多告警中快速排定优先级。
报告输出与"已知误报"的优雅处理
# 生成 JSON 报告,便于 CI 集成与审计留档 betterleaks git . --output findings.jsonJSON 报告包含扫描状态、字节数、按置信度/严重度/验证状态分类的统计计数,结构定义见 docs/schemas/findings.schema.json。
对于确认安全的样例密钥(如文档中的示例值),有两条轻量豁免路径:
- 行内豁免标记:在该行任意位置加上
betterleaks:allow(兼容gitleaks:allow)即可抑制; - 指纹忽略文件:把密钥的 SHA-256 指纹写入
.betterleaksignore,该值在任何位置、任何提交出现都会被忽略。生成指纹而不把密钥暴露进 shell 参数:
printf '%s' "$SECRET" | betterleaks fingerprint更多配置细节(过滤表达式、验证/分析逻辑)参见 docs/config.md。
实战小结:一套推荐的扫描姿势
- 日常开发:pre-commit 钩子跑
--staged,把泄漏挡在 commit 之外; - 接手仓库 / 定期审计:
betterleaks git . --include=commit-messages全历史扫一遍,大仓库配-j提速; - 安全加固:对可疑结果加
-a做身份与权限分析,优先处理"有效且高权限"的凭证; - CI/服务端:JSON 报告入库 +
--pre-receive钩子拒绝带密钥的推送; - 误报治理:行内
betterleaks:allow标记或.betterleaksignore指纹文件。
Git 不会遗忘,但 Betterleaks 可以让遗忘发生——在它变成事故之前。更多扫描模式(远程仓库 URL 扫描、GitHub/GitLab 平台资源扫描等)可参考 README.md 与 docs/scanning.md,核心 Git 扫描实现位于 sources/git.go。
【免费下载链接】betterleaksFind leaked secrets everywhere.项目地址: https://gitcode.com/gh_mirrors/be/betterleaks
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考