3.7 KiB
3.7 KiB
2026-09-11 工作日志
代码审阅(全库,安全/正确性/可优化)
结论:无 P0、无 P1 可利用漏洞;仅 P2(一致性 / 健壮性 / 性能)。
已验证「没问题」的项(勿重复排查)
- 越权:所有写接口均有归属校验 ——
getOwnedVote显式比对vote.UserID != ctx.User.ID(vote.go:388-401); question 路由挂在question.Questioner中间件组(route.go:262-274),PublishAnswer二次校验question.UserID; follow-up 写操作以question.ID为作用域(AnswerByID/UpdateAnswerByID)。profile/password/harassment/tags/features 一律用ctx.User.ID。 - SQL 注入:
internal/db全部用?绑定参数;拼接仅出现在常量/配置(dedupeUniqueFields、tagCond、randomFunc)。 - XSS:
internal/template/markdown.go白名单消毒扎实 —— stripon*、禁style、safeURL协议白名单 (http/https/mailto/相对)、拒//协议相对、强制rel="noopener noreferrer"。 - 竞态:follow-up 用事务 +
FOR UPDATE行锁;投票「一人一票」用复合唯一索引。 - GORM bool 默认值陷阱:已规避(
Enabled不加gorm:"default:true",见 feature_control.go:79-81), 且reconcileLegacyChatEnabled(:609-618)修复旧 backfill 脏行。 - 审核缓存回放无 fail-open:
AliyunTextCensorParser(aliyun.go:433-461)与QiniuTextCensorParser(qiniu.go:133-170)都会从 raw 重建Details,故Decide仍能按当前档位裁决(改档位对历史缓存同样生效)。 ⚠️ text.go:66 注释称「回放缓存结果时为 nil」是错的,需修正。
P2 清单(待用户选批后落地)
| # | 文件:行 | 问题 | 建议 |
|---|---|---|---|
| 1 | censor.go:72,111,118-125 | 缓存按原文 text 查,实际送审 RemoveTrustedURL(text),落库 Input 存原文 → 审计与实际送审不一致 + 归一化相同文本重复调 API |
归一化一次,查找/送审/落库统一用归一化文本,原文另存字段 |
| 2 | censor.go:85-102 | qiniu 缓存命中仅 Pass 才返回,aliyun 命中即返回(不看 Pass)→ 依赖「aliyun 恒为链尾」隐式前提 |
两分支语义对齐,或显式固化链尾不变量 |
| 3 | text.go:66 | 注释失真(称回放时 Details 为 nil,实际会重建) | 修正注释 |
| 4 | route/vote/vote.go:814-822 | 配额用「插入后计数」判定,非原子条件插入 → 并发可短暂超额(有界、自动结束自愈) | 改 WHERE count<quota 条件插入或 DB 计数列 |
| 5 | route/user/profile.go:194-215 | Name/Intro/各 link 无长度校验直传 db.Users.Update |
补 rune 长度校验(对齐 vote/block-word) |
| 6 | internal/db/users.go:89 | User.Email 带 json:"email"(对比 Password/BlockWords 为 json:"-")→ 潜在 PII 泄露 |
改 json:"-" |
| 7 | internal/db/db.go:215-222 | 用 conf.Database.Schema 拼 CREATE SEQUENCE(配置来源,纵深防御) |
校验/白名单 schema 标识符 |
| 8 | text.go:114-141 | RemoveTrustedURL 对 12 host × 2 protocol = 24 次整串重建 |
单次正则/一次遍历 |
另:question.go:214 提问人 token 在 URL 中(邮件链接),设计如此,会出现在邮件日志/Referer,可接受。
编译状态(延续 09-10)
- 重包
./route/user/ ./internal/route/ ./internal/db/再次 30 分钟超时(exit 124,无报错) → 判定为 1C1G 沙箱编译整图慢,非代码错误(注释改动不影响编译,20 文件gofmt -e均可解析)。 - 已确认可编译:GROUP1(security/censor、conf、form、template、shared、captcha)EXIT=0;
./internal/db/EXIT=0。 - 温缓存重试(task zGnX3L)仍在跑,25 分钟上限。