secrets-gitleaks
概述
Gitleaks 是一个秘密检测工具,用于扫描 git 仓库、文件和目录中的硬编码凭证,包括密码、API 密钥、令牌和其他敏感信息。它结合了基于正则表达式的模式匹配和香农熵分析来识别可能导致未授权访问的秘密。
这项技能提供了将 Gitleaks 集成到 DevSecOps 工作流程中的全面指导,从预提交钩子到 CI/CD 管道,重点在于在代码到达生产环境之前防止秘密泄露。
快速开始
扫描当前仓库以查找秘密:
# 安装 gitleaks
brew install gitleaks # macOS
# 或者:docker pull zricethezav/gitleaks:latest
# 扫描当前 git 仓库
gitleaks detect -v
# 扫描特定目录
gitleaks detect --source /path/to/code -v
# 生成报告
gitleaks detect --report-path gitleaks-report.json --report-format json
核心工作流程
1. 仓库扫描
扫描现有仓库以识别暴露的秘密:
# 完整仓库扫描并输出详细信息
gitleaks detect -v --source /path/to/repo
# 使用自定义配置进行扫描
gitleaks detect --config .gitleaks.toml -v
# 生成 JSON 报告以供进一步分析
gitleaks detect --report-path findings.json --report-format json
# 生成 SARIF 报告以集成到 GitHub/GitLab
gitleaks detect --report-path findings.sarif --report-format sarif
使用场景:初始安全审计、合规性检查、事件响应。
2. 预提交钩子保护
从一开始就防止秘密被提交:
# 安装预提交钩子(在仓库根目录下运行)
cat << 'EOF' > .git/hooks/pre-commit
#!/bin/sh
gitleaks protect --verbose --redact --staged
EOF
chmod +x .git/hooks/pre-commit
使用捆绑脚本来自动安装钩子:
./scripts/install_precommit.sh
使用场景:开发人员工作站设置、团队入职、强制性安全控制。
3. CI/CD 管道集成
GitHub Actions
name: gitleaks
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GitLab CI
gitleaks:
image: zricethezav/gitleaks:latest
stage: test
script:
- gitleaks detect --report-path gitleaks.json --report-format json --verbose
artifacts:
paths:
- gitleaks.json
when: always
allow_failure: false
使用场景:自动化安全门禁、拉取请求检查、发布验证。
4. 基线和增量扫描
建立安全基线并只跟踪新的秘密:
# 创建初始基线
gitleaks detect --report-path baseline.json --report-format json
# 后续扫描只检测新的秘密
gitleaks detect --baseline-path baseline.json --report-path new-findings.json -v
使用场景:遗留代码库修复、分阶段推出、合规性跟踪。
5. 配置定制
创建自定义 .gitleaks.toml 配置:
title = "自定义 Gitleaks 配置"
[extend]
# 扩展默认配置以包含自定义规则
useDefault = true
[[rules]]
id = "custom-api-key"
description = "自定义 API 密钥模式"
regex = '''(?i)(custom_api_key|custom_secret)[\s]*[=:][\s]*['"][a-zA-Z0-9]{32,}['"]'''
tags = ["api-key", "custom"]
[allowlist]
description = "全局允许列表"
paths = [
'''\.md$''', # 忽略 markdown 文件
'''test/fixtures/''', # 忽略测试固定装置
]
stopwords = [
'''EXAMPLE''', # 忽略示例密钥
'''PLACEHOLDER''',
]
使用 assets/ 中的捆绑配置模板:
assets/config-strict.toml- 严格检测(低误报)assets/config-balanced.toml- 平衡检测(推荐)assets/config-custom.toml- 自定义规则的模板
使用场景:减少误报、添加专有秘密模式、组织标准。
安全考虑
敏感数据处理
- 秘密脱敏:在日志和报告中始终使用
--redact标志以防止意外泄露秘密 - 报告安全:Gitleaks 报告包含检测到的秘密 - 视为机密,加密存储
- Git 历史记录:在 git 历史记录中检测到的秘密需要使用
git filter-repo或BFG Repo-Cleaner等工具完全移除 - 凭证轮换:所有暴露的秘密必须立即轮换,即使已从代码中移除
访问控制
- CI/CD 权限:Gitleaks 扫描需要对仓库内容和 git 历史记录的读取权限
- 报告访问:限制对包含敏感发现的扫描报告的访问
- 基线文件:基线 JSON 文件包含秘密元数据 - 使用与发现相同的控制措施进行保护
审计日志
记录以下内容以符合合规性和事件响应:
- 扫描执行的时间戳和范围(仓库、分支、提交范围)
- 检测到的秘密数量和类型
- 采取的补救措施(凭证轮换、提交历史清理)
- 误报分类和允许列表更新
合规性要求
- PCI-DSS 3.2.1:要求 6.5.3 - 防止支付应用程序中硬编码凭证
- SOC2:CC6.1 - 逻辑访问控制防止未经授权的凭证暴露
- GDPR:第 32 条 - 处理个人数据凭证的适当安全措施
- CWE-798:使用硬编码凭证
- CWE-259:使用硬编码密码
- OWASP A07:2021:识别和认证失败
捆绑资源
脚本(scripts/)
install_precommit.sh- 自动化预提交钩子安装,带有配置提示scan_and_report.py- 综合扫描,支持多种输出格式和严重性分类baseline_manager.py- 基线创建、比较和增量扫描管理
参考资料(references/)
detection_rules.md- 包含 CWE 映射的内置 Gitleaks 检测规则的全面列表remediation_guide.md- 包括 git 历史记录清理在内的逐步秘密补救程序false_positives.md- 常见的误报模式和允许列表配置策略compliance_mapping.md- 详细映射到 PCI-DSS、SOC2、GDPR 和 OWASP 要求
资产(assets/)
config-strict.toml- 高灵敏度配置(最大检测)config-balanced.toml- 适用于生产的平衡配置config-custom.toml- 带有内联文档的自定义规则模板precommit-config.yaml- 预提交框架配置github-action.yml- 完整的 GitHub Actions 工作流模板gitlab-ci.yml- 完整的 GitLab CI 管道模板
常见模式
模式 1:初始仓库审计
首次秘密扫描以进行安全评估:
# 1. 克隆带有完整历史的仓库
git clone --mirror https://github.com/org/repo.git audit-repo
cd audit-repo
# 2. 运行全面扫描
gitleaks detect --report-path audit-report.json --report-format json -v
# 3. 生成人类可读报告
./scripts/scan_and_report.py --input audit-report.json --format markdown --output audit-report.md
# 4. 查看发现并分类误报
# 编辑 .gitleaks.toml 以添加允许列表条目
# 5. 为将来的扫描创建基线
cp audit-report.json baseline.json
模式 2:开发人员工作站设置
保护开发人员免受意外秘密提交:
# 1. 本地安装 gitleaks
brew install gitleaks # macOS
# 或者使用您的操作系统的包管理器
# 2. 安装预提交钩子
./scripts/install_precommit.sh
# 3. 用虚拟提交测试钩子
echo "api_key = 'EXAMPLE_KEY_12345'" > test.txt
git add test.txt
git commit -m "test" # 应该被 gitleaks 阻止
# 4. 清理测试
git reset HEAD~1
rm test.txt
模式 3:带有基线的 CI/CD 管道
在持续集成中逐步进行秘密检测:
# 在 CI 管道脚本中:
# 1. 检查基线是否存在
if [ -f ".gitleaks-baseline.json" ]; then
# 增量扫描 - 仅新的秘密
gitleaks detect \
--baseline-path .gitleaks-baseline.json \
--report-path new-findings.json \
--report-format json \
--exit-code 1 # 新秘密时失败
else
# 初始扫描 - 创建基线
gitleaks detect \
--report-path .gitleaks-baseline.json \
--report-format json \
--exit-code 0 # 第一次扫描时不失败
fi
# 2. 为 GitHub 安全标签生成 SARIF
if [ -f "new-findings.json" ] && [ -s "new-findings.json" ]; then
gitleaks detect \
--baseline-path .gitleaks-baseline.json \
--report-path results.sarif \
--report-format sarif
fi
模式 4:自定义规则开发
添加特定于组织的秘密模式:
# 添加到 .gitleaks.toml
[[rules]]
id = "acme-corp-api-key"
description = "ACME 公司内部 API 密钥"
regex = '''(?i)acme[_-]?api[_-]?key[\s]*[=:][\s]*['"]?([a-f0-9]{40})['"]?'''
secretGroup = 1
tags = ["api-key", "acme-internal"]
[[rules]]
id = "acme-corp-database-password"
description = "ACME 公司数据库密码格式"
regex = '''(?i)(db_pass|database_password)[\s]*[=:][\s]*['"]([A-Z][a-z0-9@#$%]{15,})['"]'''
secretGroup = 2
tags = ["password", "database", "acme-internal"]
# 测试自定义规则
# gitleaks detect --config .gitleaks.toml -v
集成点
CI/CD 集成
- GitHub Actions:使用
gitleaks/gitleaks-action@v2与安全标签进行本地集成 - GitLab CI:基于 Docker 的扫描,带有用于审计跟踪的工件保留
- Jenkins:通过 Docker 或安装的二进制文件在管道阶段执行
- CircleCI:带有 orbs 支持的 Docker 执行器
- Azure Pipelines:基于任务的集成,结果发布
安全工具生态系统
- SIEM 集成:将 JSON 发现导出到 Splunk、ELK 或 Datadog 进行集中监控
- 漏洞管理:将 SARIF 报告导入 Snyk、SonarQube 或 Checkmarx
- 秘密管理:将发现结果与 HashiCorp Vault 或 AWS Secrets Manager 轮换工作流程集成
- 工单系统:自动化 Jira/ServiceNow 工单创建用于补救跟踪
SDLC 集成
- 设计阶段:在安全架构审查中包含秘密检测要求
- 开发:预提交钩子为开发人员提供即时反馈
- 代码审查:PR/MR 检查防止秘密到达主分支
- 测试:扫描测试环境和基础设施即代码
- 部署:在生产发布前进行最终验证门禁
- 运维:定期扫描部署配置和日志
故障排除
问题:误报太多
症状:合法的代码模式被标记为秘密(测试固定装置、示例、占位符)
解决方案:
- 查看发现以识别模式:
grep -i "example\|test\|placeholder" gitleaks-report.json - 添加到
.gitleaks.toml的允许列表:[allowlist] paths = ['''test/''', '''examples/''', '''\.md$'''] stopwords = ["EXAMPLE", "PLACEHOLDER", "YOUR_API_KEY_HERE"] - 对特定误报使用提交允许列表:
[allowlist] commits = ["commit-sha-here"] - 参考
references/false_positives.md了解常见模式
问题:大型仓库性能问题
症状:扫描时间过长(>10 分钟),内存使用高
解决方案:
- 使用
--log-opts限制 git 历史记录:gitleaks detect --log-opts="--since=2024-01-01" - 扫描特定分支:
gitleaks detect --log-opts="origin/main" - 使用基线方法仅扫描最近更改
- 考虑浅克隆进行初始扫描:
git clone --depth=1000 - 在多个分支或子目录上并行扫描
问题:预提交钩子阻止有效提交
症状:开发人员无法提交包含合法模式的代码
解决方案:
- 添加内联注释以绕过钩子:
# gitleaks:allow - 更新
.gitleaks.toml允许列表以适应特定模式 - 使用
--redact安全地查看发现:gitleaks protect --staged --redact - 临时绕过(谨慎使用):
git commit --no-verify - 如果模式确实需要,请与安全团队审查
问题:在 Git 历史记录中发现秘密
症状:在旧提交中检测到秘密,已从当前代码中移除
解决方案:
- 立即轮换受损凭证(最高优先级)
- 对于公共仓库,考虑使用以下工具重写整个历史记录:
git filter-repo(推荐):git filter-repo --path-glob '*.env' --invert-paths- BFG Repo-Cleaner:
bfg --delete-files credentials.json
- 强制推送清理后的历史记录:
git push --force - 通知所有贡献者重新基线/重新克隆
- 参考
references/remediation_guide.md了解详细程序 - 在安全审计日志中记录事件
问题:自定义秘密模式未被检测到
症状:组织特定的秘密未被默认规则捕获
解决方案:
- 开发正则表达式模式:在 regex101.com 上用样本秘密进行测试
- 将自定义规则添加到
.gitleaks.toml:[[rules]] id = "custom-secret-id" description = "描述" regex = '''your-pattern-here''' secretGroup = 1 # 包含实际秘密的捕获组 - 测试模式:
gitleaks detect --config .gitleaks.toml -v --no-git - 如果模式模棱两可,考虑熵阈值:
[[rules.Entropies]] Min = "3.5" Max = "7.0" Group = "1" - 用已知的真实阳性和阴性验证
高级配置
基于熵的检测
对于没有明确模式的秘密,使用香农熵分析:
[[rules]]
id = "high-entropy-strings"
description = "可能是秘密的高熵字符串"
regex = '''[a-zA-Z0-9]{32,}'''
entropy = 4.5 # 香农熵阈值
secretGroup = 0
复合规则(v8.28.0+)
检测跨多行或需要上下文的秘密:
[[rules]]
id = "multi-line-secret"
description = "具有使用上下文的 API 密钥"
regex = '''api_key[\s]*='''
[[rules.composite]]
pattern = '''initialize_client'''
location = "line" # 必须在同一行附近
distance = 5 # 在 5 行内
全局与规则特定允许列表
# 全局允许列表(最高优先级)
[allowlist]
description = "组织范围的例外"
paths = ['''vendor/''', '''node_modules/''']
# 规则特定允许列表
[[rules]]
id = "generic-api-key"
[rules.allowlist]
description = "仅适用于此规则的例外"
regexes = ['''key\s*=\s*EXAMPLE''']