Security

Git 密钥扫描与泄露防护

密钥如何泄露到 Git、git-secrets、truffleHog、Gitleaks 自动扫描、平台级检测、BFG 历史清理与 pre-commit 预防机制。

适合谁看
  • 需要配置 Git 安全认证的开发者
前置知识
  • 知道 SSH 的基本概念
  • 有命令行操作经验
常见风险
  • 密钥管理不当导致安全泄露
  • 不理解签名策略导致提效验证失败

学完这篇你会掌握什么

  • 理解 Git 密钥扫描与泄露防护 的核心作用和适用场景
  • 掌握 Git 密钥扫描与泄露防护 的基本用法和常用参数
  • 密钥如何泄露到 Git、git-secrets、truffleHog、Gitleaks 自动扫描、平台级检测、BFG 历史清理与 pre-commit 预防机制。
  • 理解 密钥如何泄露到 Git 相关的概念
  • 掌握 git-secrets 相关的操作
  • 知道在什么场景下使用该命令,什么场景下避免使用

先想一个问题

你担心 Git 仓库的安全——可能是密钥管理不到位,也可能是提交没有签名验证。你不确定自己的安全配置是否足够,也不清楚从哪里开始加固。

一句话理解

API 密钥、密码、令牌等敏感信息一旦误提交到 Git,将永久存在于历史记录中——自动化扫描、提交前钩子和历史清理工具是三道关键防线。

密钥如何泄露到 Git

# 常见泄露场景:
git add .                      # 误将 .env 添加到暂存区
git commit -m "fix config"     # config 文件包含硬编码密钥
git push origin main           # 密钥已经公开

即使在后续提交中删除了文件,密钥仍然存在于对象数据库中:

git log --all --diff-filter=D --summary  # 查找已删除文件
git show COMMIT_HASH:config.js           # 密钥仍然可见

git-secrets

通过正则匹配在提交前和历史中扫描敏感信息。

# 安装
brew install git-secrets                    # macOS
sudo apt install git-secrets                # Linux

# 注册 AWS 模式
git secrets --register-aws

# 安装 pre-commit 钩子
git secrets --install

# 扫描整个历史
git secrets --scan-history

# 添加自定义模式
git secrets --add 'api[_-]?key\s*[:=]\s*.+'
git secrets --add '(--|password|passwd)\s*[:=]\s*.+'

truffleHog

基于熵值检测——无需预定义模式,自动发现高熵字符串。

# 扫描仓库
trufflehog git https://github.com/user/repo.git

# 指定分支扫描
trufflehog git https://github.com/user/repo.git --branch main

# 扫描本地目录
trufflehog filesystem /path/to/repo

Gitleaks

基于规则的扫描工具,内置大量检测规则。

# 安装
brew install gitleaks

# 扫描仓库
gitleaks detect --source . -v

# 使用自定义配置
gitleaks detect --source . --config .gitleaks.toml

# 扫描全部历史
gitleaks detect --source . --log-opts="--all"

# 导出 JSON 报告
gitleaks detect --source . --report-format json --report report.json

.gitleaks.toml 示例:

title = "自定义 Gitleaks 配置"
[[rules]]
  id = "custom-api-token"
  description = "自定义 API 令牌模式"
  regex = '''(?i)myapp_token[ =]+[0-9a-zA-Z_-]{20,}'''
  tags = ["custom", "token"]

[[rules]]
  id = "private-key"
  description = "私钥块"
  regex = '''-----BEGIN\s?RSA\s?PRIVATE\s?KEY-----'''
  tags = ["key", "crypto"]

平台级检测

GitHub Secret Scanning

自动扫描所有公开仓库,匹配已知合作伙伴模式(AWS、Google、Azure 等),同时通知用户和供应商。

# 在私有仓库中启用:
# Settings → Code security → Secret scanning → Enable

GitLab Secret Detection

通过专用 CI 任务实现:

secret_detection:
  stage: test
  script:
    - gitlab-org/ci-cd/secret-detection
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

密钥相关 .gitignore 最佳实践

# 环境文件
.env
.env.*
.env.local
.env.production

# 密钥和凭据
**/secrets/
credentials.*
*.cred
**/config/credentials/

# 密钥文件
*.pem
*.key
*.p12
*.jks
id_rsa
id_ed25519

# 可能包含密钥的构建产物
*.log
npm-debug.log*

全局 .gitignore

git config --global core.excludesFile ~/.gitignore_global

Pre-Commit 钩子检测密钥

使用 pre-commit 框架:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: detect-private-key
  - repo: https://github.com/awslabs/git-secrets
    rev: master
    hooks:
      - id: git-secrets

手动 pre-commit 钩子(.git/hooks/pre-commit):

#!/bin/sh
git secrets --pre-commit
gitleaks protect --source .

从历史中移除密钥

BFG Repo-Cleaner

快速清理大文件或文本模式。

# 克隆镜像
git clone --mirror https://github.com/user/repo.git

# 替换敏感文本
java -jar bfg.jar --replace-text passwords.txt repo.git

# 删除特定文件
java -jar bfg.jar --delete-files .env repo.git

# 过期并垃圾回收
cd repo.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push --force

git filter-repo

基于 Python 的更强大替代方案。

pip install git-filter-repo

# 从所有历史中移除文件
git filter-repo --path .env --invert-paths

# 替换文本
git filter-repo --replace-text <(echo "AKIAIOSFODNN7EXAMPLE==>REPLACED")

防止意外提交

使用凭据管理器代替硬编码令牌:

git config --global credential.helper osxkeychain

设置 pre-push 钩子:

#!/bin/sh
# .git/hooks/pre-push
git secrets --scan || exit 1
gitleaks detect --source . -v || exit 1

关键要点

  1. 历史中的密钥是永久的——除非主动清理
  2. 平台扫描是被动的——能事后发现,不能事前预防
  3. Pre-commit 钩子最有效——在源头阻断泄露
  4. 任何泄露的密钥都视为已泄露——立即轮换
  5. 组合工具:git-secrets + Gitleaks + 平台扫描,纵深防御

给你的练习

  1. 在一个测试仓库中练习该命令的基本用法,观察执行前后的状态变化
  2. 尝试该命令的不同参数选项,对比输出结果的差异
  3. 模拟一个需要使用该命令的实际场景,完整走一遍操作流程

继续学习建议

  1. best-practices/security-with-git — Git 安全最佳实践概览
  2. security/credential-helper — 凭据管理,避免硬编码
  3. security/gpg-signing — 提交身份验证
  4. commands/git-fsck — 仓库完整性检查