[BEL] 修复生产模式验证码入口缺失与答案日志泄漏 #138

Closed
opened 2026-08-29 16:09:53 +08:00 by ila · 4 comments
Owner

状态

已完成

基本信息

  • 类型:缺陷修复 / 安全
  • 主项目:Bell
  • 主 agent:Bell agent
  • 所属 Epic:#7
  • 所属 MVP:#8
  • 来源:执行 #134 的生产 Windows 包隔离 E2E
  • 前置:#62、#131、#132、#133
  • 阻塞:#134
  • 独立运行:使用临时 PostgreSQL 和生产配置验证,不启动 Sense/Brain

复现与根因

  1. 以 Bell/server/config/settings.yml 的 mode: prod 启动当前 Bell。
  2. 登录认证器在非 dev 模式强制执行 captcha.Verify(uuid, code, true)。
  3. 现有登录页调用匿名 GET /api/v1/captcha 获取验证码。
  4. Bell 最小路由 registerBaseRouter 没有注册 captcha handler,因此生产用户无法取得有效 uuid/code,登录固定返回“验证码错误”。
  5. 现有 GenerateCaptchaHandler 会把验证码答案写入日志;不能直接开放而不先移除答案日志。

#134 首次隔离包运行证据:迁移和进程清理正常,POST /api/v1/login 返回业务码 400、消息“验证码错误”。开发配置的历史 smoke 免验证码,未覆盖该生产分支。

目标

  • 恢复 GoAdmin 生产登录页所依赖的匿名 captcha 接口。
  • 验证验证码可获取、正确答案可登录、错误答案被拒绝且一次性消费。
  • 验证验证码答案、登录密码和 token 不进入日志或通用操作审计。
  • 保持 Bell 独立 JWT、用户库、RBAC 与最小路由边界,不开放其他默认模块。

非目标

  • 不关闭生产验证码,不恢复 Sense 的免验证码策略。
  • 不修改登录页结构、认证协议、密码策略、会话期限或其他产品模块。
  • 不修改 Sense、Brain、contracts、docs 或根级部署。

已确认行为与方案草案

  • 复用当前 Bell 登录页和冻结 GoAdmin captcha 机制,不新增 UI/交互,因此无需新原型。
  • 在 Bell 已启用的匿名认证路由中只注册 GET /api/v1/captcha。
  • 删除 captcha handler 中记录明文答案的日志;保留失败日志但不得包含答案。
  • 使用真实生产配置、内存 captcha store 与隔离 PostgreSQL 做端到端登录测试。

精确 write_paths

  • Bell/server/app/admin/router/sys_router.go
  • Bell/server/app/admin/apis/captcha.go
  • Bell/server/tests/bell_production_login/**

禁止修改其他业务实现、UI、Sense、Brain、contracts、docs 和根级配置。#134 的测试/交付脚本在本缺陷单中只作为复现证据,不取得写权限。

验收标准

  • 生产配置下匿名 GET /api/v1/captcha 返回业务码 200、图片数据和非空 id。
  • 正确验证码加有效账号密码可登录;错误验证码拒绝;已使用验证码不能重放。
  • captcha 答案、密码、JWT 和登录 token 不出现在服务器日志与数据库操作审计。
  • 未认证业务 API 仍拒绝,禁用默认路由仍为 404。
  • 后端 go test ./...、go vet ./...、go build ./... 和生产 PostgreSQL 登录回归通过。
  • 提交只包含授权 Bell 路径。

风险与回退

  • 风险:匿名验证码端点可能被滥用,答案日志会绕过验证码安全边界。
  • 控制:只开放图片生成接口、沿用一次性/限时 store、移除答案日志并做泄漏检查。
  • 回退:回退该任务提交会恢复当前“生产无法登录”的已知缺陷;不得以关闭验证码作为回退替代。

文档影响

恢复当前登录页既有行为,不改变长期配置或操作方式;预计无长期 Wiki 影响。若实施发现部署或安全边界变化,先更新工单并重新确认。

## 状态 已完成 ## 基本信息 - 类型:缺陷修复 / 安全 - 主项目:Bell - 主 agent:Bell agent - 所属 Epic:#7 - 所属 MVP:#8 - 来源:执行 #134 的生产 Windows 包隔离 E2E - 前置:#62、#131、#132、#133 - 阻塞:#134 - 独立运行:使用临时 PostgreSQL 和生产配置验证,不启动 Sense/Brain ## 复现与根因 1. 以 Bell/server/config/settings.yml 的 mode: prod 启动当前 Bell。 2. 登录认证器在非 dev 模式强制执行 captcha.Verify(uuid, code, true)。 3. 现有登录页调用匿名 GET /api/v1/captcha 获取验证码。 4. Bell 最小路由 registerBaseRouter 没有注册 captcha handler,因此生产用户无法取得有效 uuid/code,登录固定返回“验证码错误”。 5. 现有 GenerateCaptchaHandler 会把验证码答案写入日志;不能直接开放而不先移除答案日志。 #134 首次隔离包运行证据:迁移和进程清理正常,POST /api/v1/login 返回业务码 400、消息“验证码错误”。开发配置的历史 smoke 免验证码,未覆盖该生产分支。 ## 目标 - 恢复 GoAdmin 生产登录页所依赖的匿名 captcha 接口。 - 验证验证码可获取、正确答案可登录、错误答案被拒绝且一次性消费。 - 验证验证码答案、登录密码和 token 不进入日志或通用操作审计。 - 保持 Bell 独立 JWT、用户库、RBAC 与最小路由边界,不开放其他默认模块。 ## 非目标 - 不关闭生产验证码,不恢复 Sense 的免验证码策略。 - 不修改登录页结构、认证协议、密码策略、会话期限或其他产品模块。 - 不修改 Sense、Brain、contracts、docs 或根级部署。 ## 已确认行为与方案草案 - 复用当前 Bell 登录页和冻结 GoAdmin captcha 机制,不新增 UI/交互,因此无需新原型。 - 在 Bell 已启用的匿名认证路由中只注册 GET /api/v1/captcha。 - 删除 captcha handler 中记录明文答案的日志;保留失败日志但不得包含答案。 - 使用真实生产配置、内存 captcha store 与隔离 PostgreSQL 做端到端登录测试。 ## 精确 write_paths - Bell/server/app/admin/router/sys_router.go - Bell/server/app/admin/apis/captcha.go - Bell/server/tests/bell_production_login/** 禁止修改其他业务实现、UI、Sense、Brain、contracts、docs 和根级配置。#134 的测试/交付脚本在本缺陷单中只作为复现证据,不取得写权限。 ## 验收标准 - [x] 生产配置下匿名 GET /api/v1/captcha 返回业务码 200、图片数据和非空 id。 - [x] 正确验证码加有效账号密码可登录;错误验证码拒绝;已使用验证码不能重放。 - [x] captcha 答案、密码、JWT 和登录 token 不出现在服务器日志与数据库操作审计。 - [x] 未认证业务 API 仍拒绝,禁用默认路由仍为 404。 - [x] 后端 go test ./...、go vet ./...、go build ./... 和生产 PostgreSQL 登录回归通过。 - [x] 提交只包含授权 Bell 路径。 ## 风险与回退 - 风险:匿名验证码端点可能被滥用,答案日志会绕过验证码安全边界。 - 控制:只开放图片生成接口、沿用一次性/限时 store、移除答案日志并做泄漏检查。 - 回退:回退该任务提交会恢复当前“生产无法登录”的已知缺陷;不得以关闭验证码作为回退替代。 ## 文档影响 恢复当前登录页既有行为,不改变长期配置或操作方式;预计无长期 Wiki 影响。若实施发现部署或安全边界变化,先更新工单并重新确认。
ila added the kind/taskproject/bellscope/independentpriority/p0 labels 2026-08-29 16:09:53 +08:00
Author
Owner

用户于 2026-08-29 明确确认方案并要求执行。已从 dev@452cd71035d6a1c2a6059dfd418950045286b1f3 创建 feature/138-bell-production-captcha;#134 的未提交现场已独立暂存,不会混入本工单。开始按精确 write_paths 实施。

用户于 2026-08-29 明确确认方案并要求执行。已从 `dev@452cd71035d6a1c2a6059dfd418950045286b1f3` 创建 `feature/138-bell-production-captcha`;#134 的未提交现场已独立暂存,不会混入本工单。开始按精确 `write_paths` 实施。
Author
Owner

实施进度(2026-08-29):已核对冻结基线 go-admin@f06540883b41d03782bb6b2c4150f298f328c6b6 的 app/other/router/gen_router.go、app/admin/apis/captcha.go,以及 go-admin-doc@424855aacf6905f3fde860c3331385cb25529a0d 的 docs/intro/advanced/router.md、tutorial0220.md。采用方式:只在 Bell 现有匿名 /api/v1 组恢复 GET /captcha,不恢复其他默认路由;丢弃验证码答案并删除答案日志。

验证进度:隔离 PostgreSQL + mode: prod 回归已通过,覆盖 captcha=200、有效验证码登录、错误与重放拒绝、未认证业务 API 拒绝、禁用默认路由 404、密码/验证码/JWT 不进入服务器日志和数据库审计。go test ./... -count=1、go vet ./...、go build ./...、git diff --check 均通过。下一步提交并创建回到 dev 的 PR。

实施进度(2026-08-29):已核对冻结基线 `go-admin@f06540883b41d03782bb6b2c4150f298f328c6b6` 的 `app/other/router/gen_router.go`、`app/admin/apis/captcha.go`,以及 `go-admin-doc@424855aacf6905f3fde860c3331385cb25529a0d` 的 `docs/intro/advanced/router.md`、`tutorial0220.md`。采用方式:只在 Bell 现有匿名 `/api/v1` 组恢复 `GET /captcha`,不恢复其他默认路由;丢弃验证码答案并删除答案日志。 验证进度:隔离 PostgreSQL + `mode: prod` 回归已通过,覆盖 captcha=200、有效验证码登录、错误与重放拒绝、未认证业务 API 拒绝、禁用默认路由 404、密码/验证码/JWT 不进入服务器日志和数据库审计。`go test ./... -count=1`、`go vet ./...`、`go build ./...`、`git diff --check` 均通过。下一步提交并创建回到 `dev` 的 PR。
Author
Owner

实施完成,等待验收

  • 分支:feature/138-bell-production-captcha
  • 提交:cabc29c18b88218c399a6bb7d506efeef4826d32
  • PR:#139(目标 dev,mergeable)
  • 实现:只恢复匿名 GET /api/v1/captcha;验证码答案不再保留到变量或日志;未恢复其他默认模块。
  • 生产回归:隔离 PostgreSQL + config/settings.yml(mode: prod)通过,结果为 captcha=200 valid_login=200 wrong_rejected=true replay_rejected=true secrets_absent=true。
  • 全量验证:go test ./... -count=1、go vet ./...、go build ./...、git diff --check 全部通过。
  • 安全边界:密码、验证码答案、JWT/token 未进入服务器日志、sys_login_log 或 sys_opera_log;未认证 Bell API 仍拒绝,未启用默认路由仍为 404。
  • 范围:提交仅包含工单授权的 4 个 Bell 文件。
  • 文档:恢复现有登录页既有行为,无长期 Wiki 影响,因此未修改 Wiki、未运行镜像同步。
  • 未验证:等待用户通过 PR/运行环境进行人工验收;验收前不合入 dev、不关闭 #138。
## 实施完成,等待验收 - 分支:`feature/138-bell-production-captcha` - 提交:`cabc29c18b88218c399a6bb7d506efeef4826d32` - PR:#139(目标 `dev`,mergeable) - 实现:只恢复匿名 `GET /api/v1/captcha`;验证码答案不再保留到变量或日志;未恢复其他默认模块。 - 生产回归:隔离 PostgreSQL + `config/settings.yml`(`mode: prod`)通过,结果为 `captcha=200 valid_login=200 wrong_rejected=true replay_rejected=true secrets_absent=true`。 - 全量验证:`go test ./... -count=1`、`go vet ./...`、`go build ./...`、`git diff --check` 全部通过。 - 安全边界:密码、验证码答案、JWT/token 未进入服务器日志、`sys_login_log` 或 `sys_opera_log`;未认证 Bell API 仍拒绝,未启用默认路由仍为 404。 - 范围:提交仅包含工单授权的 4 个 Bell 文件。 - 文档:恢复现有登录页既有行为,无长期 Wiki 影响,因此未修改 Wiki、未运行镜像同步。 - 未验证:等待用户通过 PR/运行环境进行人工验收;验收前不合入 `dev`、不关闭 #138。
ila closed this issue 2026-08-29 16:27:48 +08:00
Author
Owner

用户于 2026-08-29 明确验收通过。PR #139 已合入 dev,merge commit 86c3e79121b9db9239dc7a1062bdd15540e25336;生产验证码入口、一次性校验及敏感日志修复正式进入开发基线。工单关闭,#134 的阻塞解除。无长期 Wiki 变化,未执行 Wiki 同步。

用户于 2026-08-29 明确验收通过。PR #139 已合入 `dev`,merge commit `86c3e79121b9db9239dc7a1062bdd15540e25336`;生产验证码入口、一次性校验及敏感日志修复正式进入开发基线。工单关闭,#134 的阻塞解除。无长期 Wiki 变化,未执行 Wiki 同步。
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ila/yovision#138