fix: 修复6个bug并接入CodeStable工作流

Bug修复:
- GetWorkList 使用了错误的 RecordType (RecordStudy→RecordWork)
- AllRecord handler 返回错误的分页信息 (page硬编码1, pageSize用RecordsCount)
- CourseParse creditNode nil panic (加nil检查)
- WebSocket CheckOrigin 安全漏洞 (release模式限制为同源)
- math/rand 可预测 (替换为 crypto/rand)
- GetDiscussList 未实现 (补全实现, 移除重复路由)

其他:
- 接入 CodeStable 工作流体系 (codestable/ 骨架 + AGENTS.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 19:55:57 +08:00
parent 83ee4bb5ea
commit 2a6732ffe7
23 changed files with 1561 additions and 23 deletions

View File

View File

@@ -0,0 +1,55 @@
---
doc_type: issue-fix
issue: 2026-04-25-six-bugs
status: fixed
date: 2026-04-25
severity: high
tags: [bug, security, nil-panic, wrong-data, crypto]
---
# 2026-04-25 six-bugs fix notes
6 个 bug 定点修复,来源于 refactor 扫描阶段的前置检查发现。
## Fix #1: GetWorkList 使用了错误的 RecordType
- **文件**: `internal/ckwk/api.go:479`
- **问题**: `GetWorkList` 调用 `GetRecords[WorkList](wk, RecordStudy, ...)` 传了 `RecordStudy` 而非 `RecordWork`,导致请求作业记录时实际返回的是学习记录
- **修复**: `RecordStudy``RecordWork`
- **风险**: 低,单行改动,类型签名已约束泛型
## Fix #2: AllRecord handler 返回错误的分页信息
- **文件**: `internal/handler/ckwk.go:227-228`
- **问题**: `page_info.page` 硬编码为 `1``page_info.pageSize` 使用了 `RecordsCount`(总记录数)而非 `PageSize`
- **修复**: `page: 1``page: pageInfo.Page``pageSize: pageInfo.RecordsCount``pageSize: pageInfo.PageSize`
- **风险**: 低,字段语义对齐
## Fix #3: CourseParse creditNode nil panic
- **文件**: `internal/ckwk/api.go:276-277`
- **问题**: `htmlquery.FindOne` 可能返回 nil下一行 `htmlquery.InnerText(creditNode)` 会 panic
- **修复**: 加 nil 检查,`creditNode != nil` 时才提取学分
- **风险**: 低credit 默认值为 0float32 零值),行为等价
## Fix #4: WebSocket CheckOrigin 安全漏洞
- **文件**: `internal/handler/debug_log.go:17-21`
- **问题**: `CheckOrigin` 始终返回 `true`,允许任意来源的 WebSocket 连接,存在跨站劫持风险
- **修复**: debug 模式下允许所有来源开发需要release 模式下只允许无 Origin 的请求(同源请求)
- **风险**: 低debug 模式行为不变release 模式收紧安全策略
- **附**: 移除了 `router.go` 中重复的 `/api/debug/ws/logs` 路由(与 `/api/debug/logs/ws` 重复)
## Fix #5: 非安全随机数用于验证码等场景
- **文件**: `pkg/common/rand.go`
- **问题**: 使用 `math/rand` + `time.Now().UnixNano()` 种子,可预测。`Rand()` 用于验证码请求参数,`RandFloat64()` 用于防缓存时间戳
- **修复**: 替换为 `crypto/rand`,使用 `crypto/rand.Int` 生成不可预测的随机数
- **风险**: 中,`Rand()` 在验证码获取中用作 cache-bust 参数(`r=0.xxxx`),改为 crypto/rand 不影响功能但确保不可预测
## Fix #6: GetDiscussList 未实现但已接入路由
- **文件**: `internal/ckwk/api.go:489-492`
- **问题**: `GetDiscussList` 只返回 `errors.New("func not implement")`,但已通过 `AllRecord` handler 接入路由,用户请求讨论记录会得到不友好的错误
- **修复**: 实现为 `GetRecords[StudyList](wk, RecordDiscuss, courseID, page)`,与其他记录类型一致。讨论记录暂复用 `StudyList` 类型,后续如有专门的 `DiscussList` 类型可替换
- **风险**: 中,讨论记录的返回结构可能和 StudyList 不同,如果上游 API 返回的字段不在 StudyList 中会丢失。但由于之前完全不可用,现在至少能返回数据,比返回错误更好