fix(admin): secure proxied model mutations
Staging Backend Quality Gate / validate (push) Successful in 19m41s
Staging Backend Quality Gate / publish (push) Successful in 28m13s

This commit is contained in:
Jesse_Chen
2026-08-08 01:26:21 +08:00
parent c30b4b906b
commit 99e2abe9bc
9 changed files with 275 additions and 58 deletions
+16
View File
@@ -2489,3 +2489,19 @@
- 相关记录:BUG-145
- 复发自:无(staging bootstrap deadlock 的独立 health contract 根因)
- 修复版本:待 follow-up commit / gate
## BUG-146 | staging 后台写请求把 Caddy 上游协议误当公开来源
- 状态:resolvedlocal candidate,未 push / deploy
- 首次发现:2026-08-07
- 最近更新:2026-08-07
- 影响面:所有经 `requireAdminMutation` 的后台写接口、`admin.staging.jyotisha.chat` 模型管理写操作;普通 staging 用户域名、其他后台功能的通用 `ReasonActionModal` 与 production 未改动。
- 用户现象:管理员在独立后台域名提交 `POST /api/admin/models` 时,浏览器 `Origin` 为 HTTPS 公开后台域名,但 Caddy 转发后的 Route Handler 请求 URL 使用上游 HTTP 协议,旧校验因此返回 403 `请求来源不可信`
- 触发条件:请求经 staging Caddy `reverse_proxy web:3000` 进入 Next.js,公开 origin 与上游 `request.url` 协议不同;旧 `isSameOriginAdminMutation` 只比较这两个 origin,未核对 Caddy 提供的公开 Host/Proto 头。
- 根因:共享后台 mutation guard 把应用上游 URL 当作浏览器公开来源真值,没有结合既有 `ADMIN_USER_ORIGIN`、原始 `Host` 与 Caddy 的 `X-Forwarded-Host` / `X-Forwarded-Proto`;因此合法后台请求被拒绝,同时也不能安全地仅信任任意 forwarded host。
- 修复:`requireAdminMutation` 统一调用可测试的共享来源策略;配置 `ADMIN_USER_ORIGIN` 时要求浏览器 Origin 精确匹配、`Host` 与规范化后的 forwarded host 一致、公开 host/proto 精确匹配后台 origin,缺失、歧义、畸形或冲突的 forwarded 值全部 fail closed;未配置后台 origin 的既有直连环境继续使用严格 same-origin fallback。复用 identity host 规范化 helper,未新增同义 envstaging Caddy 继续在用户域名对 `/admin*``/api/admin/*` 返回 404。模型管理同时删除 saveProvider/saveDraft/publish/rollback 的客户端“操作原因”字段与交互,服务端分别注入固定中文审计说明后继续传给原 DB procedure 的非空 reason 参数;通用 `ReasonActionModal` 未改动。
- 验证:`npx tsx --test tests/admin-http-origin.test.ts tests/admin-model-management-ui-contract.test.ts tests/identity-host-routing.test.ts tests/admin-reauth.test.ts tests/health-deployment.test.ts`34 passed);相关 ESLint、`git diff --check` 与最终差异审查见本提交验证记录。
- 防复发:后台 mutation 来源测试必须同时覆盖合法 admin Origin + 公开 host/proto、错误 Origin、普通 staging host、Host/forwarded host 冲突、逗号多值、畸形 host、缺失 proto 与非法 `ADMIN_USER_ORIGIN`;模型管理合同必须拒绝客户端 reason,并确认四个固定审计说明仍传入现有 procedure。
- 相关记录:BUG-134、BUG-138、BUG-139
- 复发自:无
- 修复版本:本地候选提交(未 push / deploy