返回博客

修完一个 Bug,下一轮 Review 又出同类坑——同领域扫描缺失的代价

某后台管理系统在 Code Review 里发现了一个密码处理逻辑的问题:setPassword() 方法的三态逻辑写错了,提交时未带新密码的请求会意外覆盖旧密码。修复、验证、合并,一切顺利。

然而下一轮 Review 又发现:同一个 setPassword() 里,密码长度完全没有校验,8 位弱密码可以直接入库。两个问题同在一个方法里,却花了两轮完整的 Review + 修复 + 验证周期。仔细一想,如果第一次修复时顺手 grep -r "password" 扫一遍,这两个问题本可一次清零。

现象

单点修复之后,同一领域的其他代码没有被检查。结果是:

  • 第 N 轮 Review 修掉一个坑
  • 第 N+1 轮 Review 又发现相邻坑
  • 每轮都要走完「发现 → 描述 → 修复 → 验证 → 合并」全链路
  • 总成本 = 单次成本 × 坑的数量,而非一次性处理的线性成本

类似的案例:

  • 修了某处 intval($id) 截断雪花 ID,其他十几处 intval() 调用原封不动
  • 修了一处 v-html 未过滤的 XSS,同文件其他 v-html 没人看
  • 修了一处 LIKE '%' . $input 通配符注入,所有 LIKE 拼接照旧

根因

问题不是「工程师修得不认真」,而是修复动作的默认边界只是当前报告的那一处。没有任何流程或提示要求做同领域扫描,所以每次都是点修——把一个症状压下去,下一个留在下一轮。

这本质上是一个遗漏成本被低估的问题。因为第一轮修复者看不到「下一轮还会发现同类问题」这个后果,自然不会主动扩大扫描范围。

坑:修完报告的那处就停手

修复某个领域(密码、ID、权限、SQL 拼接)的 bug 之后,如果不主动 grep 搜索同一关键词在整个模块的分布,同类问题会在后续 Review 中一个接一个冒出来,每次都要重启整个修复流程,总成本数倍于一次扫清。

正解

修复一个 bug 之后,立即做同领域扫描,一次性消灭同类问题。具体五步:

  1. 修复目标 bug(这一步不变)
  2. 识别领域关键词:这个 bug 属于哪个语义域?passwordidv-htmlLIKEtoken……
  3. grep 搜索整个模块grep -rn "password" app/api/controller/
  4. 逐处检查:输入校验、存储安全、输出过滤、边界条件、类型安全
  5. 一次性修完所有同类问题,commit message 注明扫描范围
# 密码领域扫描示例
grep -rn "password" app/api/controller/
 
# 雪花 ID 安全扫描
grep -rn "intval(\$.*id" app/
 
# XSS v-html 扫描
grep -rn "v-html" src/
 
# SQL LIKE 注入扫描
grep -rn "LIKE '%" app/model/

常见领域关键词速查表:

| 领域 | 关键词 | |------|--------| | 密码处理 | password, hash, bcrypt | | ID 安全 | intval($id, (int)$id | | XSS 防护 | v-html, innerHTML, dangerouslySetInnerHTML | | SQL 注入 | LIKE '%', whereRaw(, $_GET[ | | 权限校验 | checkAuth, isAdmin, hasPermission |

正解:修复后立刻 grep 同领域关键词

将「同领域扫描」作为修复流程的标准后置步骤写进 checklist 或 prompt 模板。只要 grep 一次,同一领域内的所有潜在坑都进入视野,一次性修完,不留尾巴给下一轮 Review。

一句话外卖

修 bug 的最小单位不是「一个问题」,而是「一个领域」——修完立刻 grep 同类,一次扫清,比多轮 Review 便宜得多。