audit-remote-secret-leaks
Use when a git project may have leaked private information, credentials, tokens, keys, passwords, PII, internal URLs, or secrets into pushed remote branch or tag history, or when local staged, unstage
SKILL.md.claude/skills/audit-remote-secret-leaks/SKILL.md
GitHub远程敏感信息泄露审计 (audit-remote-secret-leaks)
面向项目/仓库级敏感信息泄露排查。核心目标是判断已经推送到远程仓库的 git 历史中是否包含隐私或敏感信息,同时统计尚未推送到远程的风险内容,并产出带证据、影响范围和通用修复方案的报告。
核心原则
- 远程优先:先审计
refs/remotes/*指向的已推送历史,再看本地未推送内容。 - 只读审计:审计阶段只收集证据和统计,不删除文件、不改写历史、不强推。
- 证据脱敏:报告中不得完整展示密钥、密码、Token、私钥、Cookie、个人身份信息等敏感值。
- 范围透明:清楚标注审计了哪些远程、分支、提交范围、工作区状态和扫描方法。
- 修复先轮换:一旦敏感值已推送远程,删除提交不等于安全;先建议撤销/轮换凭据,再考虑历史清理。
- Do not validate live secrets:不要主动调用外部服务验证真实凭据是否有效,除非用户明确要求并确认风险。
- sanitized scanner output:扫描器原始输出可能包含完整敏感值;报告只能引用脱敏后的摘要和证据。
使用边界
使用本 skill:
- 用户要求检查项目是否把隐私、密钥、Token、密码、私钥、证书、个人身份信息或内部地址提交到远程仓库。
- 用户要求审计 git history、remote repository、pushed commits、远程历史、已推送提交中的敏感信息泄露。
- 用户还希望同时查看未提交、已暂存、未暂存、未跟踪、本地领先远程的内容是否存在泄露风险。
不要使用本 skill:
- 只做普通代码质量审查或安全代码审查,改用
code-review-deep-zh。 - 只读懂项目结构,改用
code-read-deep-project。 - 用户要求立即删除提交、改写历史或强推;本 skill 可给方案,但执行前必须单独确认。
前置确认
- 确认当前目录是 git 仓库根或能定位到仓库根。
- 确认是否存在远程仓库:
git remote -v。 - 说明默认审计范围:
- 远程历史:所有
refs/remotes/*,以及已获取的refs/tags/*。 - 未推送内容:工作区、暂存区、未跟踪文件、ignored 文件、stash、本地领先上游的提交。
- 远程历史:所有
- 如果用户指定远程、分支、路径、时间段或提交范围,以用户指定为准并在报告中记录。
- 如果需要联网刷新远程引用,运行
git fetch --all --prune前按当前环境权限处理;无法刷新时继续审计本地已有远程跟踪引用,并在报告中标注。
审计流程
按顺序执行,不要跳阶段。
阶段 1:仓库和远程范围确认
收集基础信息:
git rev-parse --show-toplevelgit status --short --branchgit remote -vgit branch -vvgit for-each-ref refs/remotes refs/tags --format="%(refname:short) %(objectname:short) %(committerdate:iso8601)"git tag -lgit lfs ls-files(如果安装了 Git LFS)git submodule status --recursive(如果存在.gitmodules)
报告中记录:
- 仓库根目录。
- 远程名称和 URL(可对私有 URL 做脱敏)。
- 当前分支、上游分支、默认远程 HEAD。
- Remote tag scope:本次纳入审计的 tag 范围,以及是否能确认它们来自远程。
- Git LFS / submodule 覆盖情况:若未扫描,作为限制说明。
- 最近一次
fetch是否成功。
阶段 2:敏感信息类型准备
加载 references/sensitive-patterns.md,按类型建立检查清单。优先关注:
- API Key、Access Key、Secret Key、Token、Cookie、Session。
- Password、数据库连接串、服务账号凭据。
- Private key、SSH key、证书、keystore。
- 云厂商凭据、CI/CD 凭据、Webhook secret。
- PII、身份证件、手机号、邮箱、客户数据。
- Internal address、内网域名、VPN、堡垒机、管理后台地址。
如果项目有特定技术栈或云厂商,补充对应模式;例如 AWS、Azure、GCP、阿里云、腾讯云、GitHub、GitLab、npm、PyPI、Docker Registry。
阶段 3:Remote history audit
目标是审计已经推送到远程的历史,不要只看当前工作区。
推荐顺序:
- 刷新并列出远程引用:
git fetch --all --prune --tagsgit for-each-ref refs/remotes refs/tags --format="%(refname:short) %(objectname)"
- 枚举远程提交范围:
git rev-list --remotes --tags- 如用户指定范围,使用指定的 remote ref、commit range 或 pathspec。
- 如果本地 tag 可能包含未推送 tag,在报告中标注 tag 来源限制,不要把无法确认来源的 tag 直接说成已推送。
- 使用可用的专用扫描器:
- 如果仓库已有
gitleaks、trufflehog、detect-secrets等工具配置,优先使用现有配置。 - 运行前先查看工具
--help,确认当前版本支持的历史扫描参数。 - 记录工具名称、版本、命令、配置文件和退出结果。
- 如果仓库已有
- 手工 git 证据交叉检查:
- 用
git log --remotes --tags -G <regex> --pickaxe-regex -- <paths>查找远程分支和 tag 历史 diff 中出现过的敏感模式。 - 用
git grep -I -n -E <regex> <remote-or-tag-commit> -- <paths>对可疑提交树做 blob 内容检查。 - 用
git log --remotes --tags --name-only --pretty=format:查找敏感文件名,如.env、.npmrc、.pypirc、id_rsa、*.pem、*.p12、kubeconfig。
- 用
- 检查 Git LFS 和 submodule 边界:
- 如果存在 Git LFS,检查
.gitattributes与git lfs ls-files。Git 历史中的 LFS pointer 不等于真实对象内容;实际 LFS 对象若未下载或无权限扫描,必须写成覆盖限制。 - 如果存在 submodule,使用
git submodule status --recursive列出子仓库。子模块是独立 git 历史;除非用户要求纳入,否则不要假装已覆盖。
- 如果存在 Git LFS,检查
- 对命中项做置信度判断:
- High:真实凭据格式、私钥块、带有效上下文的 secret 变量、连接串含账号密码。
- Medium:疑似 Token/key 但无法确认有效性。
- Low:测试 fixture、示例值、明显占位符或已脱敏文本。
每条远程历史命中至少记录:
- 类型、置信度、是否已推送远程。
- 首次出现提交、最近仍存在提交、涉及远程引用。
- 文件路径、行号或 blob 位置。
- 脱敏证据片段。
- 影响判断和建议动作。
阶段 4:Unpushed content statistics
统计尚未推送到远程的内容,区分不同来源:
- 工作区状态:
git status --porcelain=v1 --branch - 已暂存差异:
git diff --cached - 未暂存差异:
git diff - 未跟踪文件:
git ls-files --others --exclude-standard - ignored 文件:
git ls-files --others --ignored --exclude-standard - stash:
git stash list,必要时用git stash show -p stash@{n}只读检查并脱敏记录。 - 本地领先上游的提交:
git log @{u}..HEAD --oneline --decorate;如果没有上游,说明无法直接判断并改用远程默认分支作参考。
对这些内容执行与远程历史一致的敏感模式检查,但报告中标记为未推送或本地待推送风险。统计至少包括:
- 命中总数,按来源分组:staged、unstaged、untracked、ignored、stash、local-only commits。
- 命中文件数和高风险命中数。
- 是否存在即将随下一次 push 进入远程的内容。
- 建议在提交/推送前如何清理。
阶段 5:证据脱敏和去重
不得在报告中输出完整敏感值。使用以下方式表达证据:
- 保留变量名、文件路径、行号、提交号。
- 值只显示短前缀和长度,例如
ghp_****(len=40)。 - 私钥只说明块类型,例如
BEGIN OPENSSH PRIVATE KEY,不粘贴正文。 - PII 只展示字段名、数量和类别,不展示完整个人数据。
- 对同一敏感值跨多个提交重复出现的情况合并为一个发现项,并记录传播范围。
- 扫描器日志、JSON 或 SARIF 结果只保留 sanitized scanner output;如果工具输出含完整 secret,先脱敏再汇总,不把原始输出贴进报告。
- 不主动验证真实 Token、密码或 key 是否可用;验证动作可能扩大审计范围并触发外部系统日志。
报告输出
使用 references/report-template.md 的结构。报告必须包含:
- Audit summary:整体风险等级、是否发现已推送远程泄露、是否发现未推送风险。
- Scope:审计范围、远程引用、提交范围、工作区范围、工具和限制。
- Remote tag scope:tag 是否纳入、来源是否可确认。
- Remote history findings:已推送远程历史命中记录。
- Unpushed content statistics:未推送内容统计和命中记录。
- Local stash and ignored files:stash 与 ignored 文件覆盖情况。
- General remediation:通用修复方案。
如果没有发现命中,也要输出审计范围、方法、限制和预防建议,不能只说“没问题”。
通用修复方案 (General remediation)
按风险分层给建议,不在未确认前执行破坏性操作。
已推送到远程
- 立即撤销或轮换凭据:API key、Token、密码、证书、Webhook secret、数据库密码等先在来源系统失效化。
- 评估暴露面:确认远程仓库可见性、分支、tag、fork、release、CI 日志、缓存和包制品是否也含敏感值。
- 清理当前代码:移除敏感值,改用环境变量、secret manager、加密配置或运行时注入。
- 改写历史:需要时使用
git filter-repo或 BFG 清理历史;执行前要求用户确认范围和备份策略。 - 安全推送:清理后使用
git push --force-with-lease,并明确提示会影响协作者历史。 - 协作者同步:通知团队重新 clone 或按指定步骤重置本地分支,避免旧提交再次推回远程。
- 远程平台处理:必要时联系 GitHub/GitLab/托管平台清理缓存、PR diff、release、artifact 或搜索索引。
未推送到远程
- 从工作区或暂存区移除敏感值。
- 如果在本地提交中,使用 amend、interactive rebase 或 reset 清理;执行前确认不会丢失用户未保存工作。
- 更新
.gitignore,例如忽略.env、本地证书、密钥文件、临时导出文件。 - 在推送前重新运行扫描,确认命中消失。
长期预防
- 增加 pre-commit secret scanning。
- 在 CI 中加入 secret scanning,并阻止高风险命中合并。
- 为示例配置使用
.example文件和占位符。 - 使用最小权限、短期凭据和自动轮换。
- 为敏感配置建立团队约定和安全清单。
常见错误
- 只扫描当前工作区,漏掉已经推送到远程的历史提交。
- 只扫描远程分支,漏掉已经推送的 tag、release 指向或 tag-only 提交。
- 把 Git LFS pointer 当成真实 LFS 对象内容,或者默认子模块已被主仓库审计覆盖。
- 漏掉 stash 和 ignored 文件中尚未推送但高风险的本地敏感信息。
- 报告中粘贴完整密钥,造成二次泄露。
- 拿真实 Token 调外部接口做“有效性验证”,扩大泄露面。
- 发现远程泄露后只删除文件,不撤销或轮换凭据。
- 没有区分“已推送远程”和“未推送本地风险”。
- 在未确认范围和影响前执行
git filter-repo、BFG、git reset --hard或强推。 - 把测试用例、示例值和真实凭据混为一谈,没有做置信度判断。
交付前自检
- 已说明远程引用是否刷新成功。
- 已审计
refs/remotes/*、refs/tags/*或用户指定的远程范围。 - 已说明 Git LFS 和 submodule 是否覆盖。
- 已统计 staged、unstaged、untracked、ignored、stash、local-only commits。
- 已避免验证真实凭据有效性。
- 所有证据均已脱敏。
- 已区分 High/Medium/Low 置信度。
- 已给出已推送远程和未推送内容的不同修复路径。
- 未执行删除、历史改写、强推等破坏性操作,除非用户另行明确确认。