--- 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 默认值为 0(float32 零值),行为等价 ## 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 中会丢失。但由于之前完全不可用,现在至少能返回数据,比返回错误更好