修完一个 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 之后,立即做同领域扫描,一次性消灭同类问题。具体五步:
- 修复目标 bug(这一步不变)
- 识别领域关键词:这个 bug 属于哪个语义域?
password、id、v-html、LIKE、token…… - grep 搜索整个模块:
grep -rn "password" app/api/controller/ - 逐处检查:输入校验、存储安全、输出过滤、边界条件、类型安全
- 一次性修完所有同类问题,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 |
将「同领域扫描」作为修复流程的标准后置步骤写进 checklist 或 prompt 模板。只要 grep 一次,同一领域内的所有潜在坑都进入视野,一次性修完,不留尾巴给下一轮 Review。
一句话外卖
修 bug 的最小单位不是「一个问题」,而是「一个领域」——修完立刻 grep 同类,一次扫清,比多轮 Review 便宜得多。