Skip to content

v0.3.1 增量:历史 Secret 检查与脱敏

历史增量说明。 本文记录 v0.3.1 开发阶段的 secret-history 增量;v0.5.0 当前完整边界以安全文档和发布说明为准。

基线:main / 8739b01318b27ff253d45ce7d3e76350622af83a。 这是独立候选补丁,不代表 v0.3.1 全部完成或已发布。

修复

旧 finish 仅扫描 base 到当前工作树的净 diff。如果提交 A 引入凭证、提交 B 删除凭证,最终 diff 可以没有该内容,但 A 仍可能被推送。

现在 finish 保留原有候选 diff 检查,额外扫描固定 base_sha..HEAD 范围内 各提交的新增文本,包括合并提交相对于每个 parent 的独立 diff。 不根据历史 pushed 标记或 cached remote-tracking ref 跳过扫描;已推送但 仍位于这个范围内的提交会再次检查。这是有意的保守策略,不是精确的 Git 网络传输对象集合,也不是对仓库全部历史的审计。

同时修复:

  • EXAMPLE、YOUR_TOKEN 等词出现在一行中,不再豁免整行的凭证匹配。 自动 whole-line placeholder 例外已移除。模板使用 <token> 等不满足 真实凭证格式的值;credential-shaped 测试值需要显式误报审阅。
  • 用 hunk 边界识别新增行,避免把以 ++ 开头的文件内容误当作 diff header。
  • 按 LF 而不是所有 Unicode 行分隔符拆分 patch,避免漏掉同一新增行后半段。
  • finding 不返回原始命中源码行,而返回类型、路径及可用的 commit SHA。
  • finish 的展示 diff 使用脱敏版本;snapshot 仍绑定原始 diff,不能因两个值 脱敏后相同而复用旧 review。
  • 脱敏覆盖引号中的普通 secret assignment,以及完整/被截断的 private-key block。

失败关闭与边界

历史扫描最多 256 个提交、8 MiB patch,最长 300 秒,且不能超过用户命令 超时配置。Git 输出使用有界读取,不先无限量 capture 再截断。

浅克隆、不可读对象、非祖先 base、legacy grafts、超限/超时、非 UTF-8/NUL 二进制历史、submodule 变化等无法获得该文本扫描范围的完整证据时,finish 被阻断,并报告 history coverage_complete: false。--allow-secret-match 只能覆盖完整扫描中的显式误报,不能把缺失的扫描证据当作成功。

固定的本地 Git 读取不调用 diff/textconv helper,不使用 replace objects, 不交互获取凭证,也不允许扫描过程进行 Git 协议访问。

这仍是高信号格式的启发式检测,不是 DLP 或 sandbox。扫描范围不包含 base 之前的历史、commit message、外部 LFS 对象、submodule 内部内容或任意编码 后的秘密。原有候选 working-tree diff / reviewability 边界并未被替换为 完整 blob/index 审计;候选路径解析、Git filter/attribute 等更广泛边界需要 后续独立加固。coverage_complete 仅描述已声明扫描范围是否完整执行,不是 “没有任何形式秘密”的保证。

本补丁不改变低层手工 commit/push 路径,不引入 history rewrite、force-push、 自动 merge、额外模型调用或权限扩展。MCP job-log 与 CLI CI-log 的统一有界 抓取/脱敏、进程树控制、handoff 统一和 workspace locking 仍在后续清单中。

遇到真实凭证

先撤销/轮换,再人工处理尚未发布历史。仅从工作树删除文件并新建提交不足以 消除历史中的凭证。不要用 --allow-secret-match 放行真实凭证。 工具不会替用户自动改写已发布历史。

验证

test_history_scan.py 包含真实临时 Git 历史测试与 scanner 回归测试; test_finish_history.py 使用真实 WorkspaceManager 验证历史/candidate 阻断、 零写入、误报覆盖边界及 snapshot 绑定;原 finish 单元测试保留并在 history I/O 边界使用 mock,真实集成测试不 mock scanner。

uv run python -m unittest discover -s tests -v

Git 语义参考:官方 git-log(--diff-merges=separate、--text、 --no-textconv)和 git-replace(--no-replace-objects)文档。