fix anwser token and database issus
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# 2026-09-11 工作日志
|
||||
|
||||
## 代码审阅(全库,安全/正确性/可优化)
|
||||
|
||||
结论:**无 P0、无 P1 可利用漏洞**;仅 P2(一致性 / 健壮性 / 性能)。
|
||||
|
||||
### 已验证「没问题」的项(勿重复排查)
|
||||
|
||||
1. **越权**:所有写接口均有归属校验 —— `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`。
|
||||
2. **SQL 注入**:`internal/db` 全部用 `?` 绑定参数;拼接仅出现在常量/配置(dedupeUniqueFields、tagCond、randomFunc)。
|
||||
3. **XSS**:`internal/template/markdown.go` 白名单消毒扎实 —— strip `on*`、禁 `style`、`safeURL` 协议白名单
|
||||
(http/https/mailto/相对)、拒 `//` 协议相对、强制 `rel="noopener noreferrer"`。
|
||||
4. **竞态**:follow-up 用事务 + `FOR UPDATE` 行锁;投票「一人一票」用复合唯一索引。
|
||||
5. **GORM bool 默认值陷阱**:已规避(`Enabled` 不加 `gorm:"default:true"`,见 feature_control.go:79-81),
|
||||
且 `reconcileLegacyChatEnabled`(:609-618)修复旧 backfill 脏行。
|
||||
6. **审核缓存回放无 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 分钟上限。
|
||||
Reference in New Issue
Block a user