# OCDP 系统测试 Bug 报告 **测试日期:** 2026-05-11 **测试环境:** http://10.6.80.114:18080 **集群:** k3s (dbf824f1-9962-4d8e-881e-870c75fdb6f5), k8s (23880994-dfe4-48d0-abc0-b49692cc630a) **Harbor:** harbor.bwgdi.com (83b823af-873b-457c-912c-9ccde3cb12e6) --- ## 测试团队 | Agent | 角色 | 账号 | |-------|------|------| | user-a-agent | 前端 UI 测试 | test-user-a / TestUserA123! | | user-b-agent | API/部署测试 | test-user-b / TestUserB123! | | user-c-agent | 权限隔离测试 | test-user-c / TestUserC123! | | security-agent | 安全测试 | admin + 普通用户 | --- ## Bug 列表 (按严重度排序) ### P0 - Blocker (核心功能不可用) | ID | 标题 | 发现者 | 页面/端点 | 描述 | |----|------|--------|-----------|------| | BUG-001 | **Launch 按钮点击无任何反应** | user-a | `/artifact/registries` (TagCard) | Chart Browser 中 TagCard 的 "Launch" 按钮显示为可用状态 (`is_enabled() == True`),但点击后无任何效果:不弹出 Launch Modal,无 URL 变化,无控制台错误。**核心"一键部署"流程完全阻塞** | | BUG-002 | **SPA 直接路由返回空白页面** | user-a | `/clusters`, `/registries`, `/monitoring`, `/launch` | 直接访问 SPA 旧路由时只渲染 `
` 空壳,React SPA 无法挂载。代码中已定义 redirect 映射但未生效(如 `/clusters` → `/configuration/clusters`) | ### P1 - 高 (High) | ID | 标题 | 发现者 | 页面/端点 | 描述 | |----|------|--------|-----------|------| | BUG-003 | DELETE 实例返回 404 但实际成功删除 | user-b, user-c | `DELETE /clusters/{id}/instances/{id}` | 删除操作正确触发 `pending-delete` 状态转换,但 HTTP 返回 **404**(空 body),非预期 202/204。客户端误判为失败 | | BUG-004 | DELETE 实例返回空响应体 | user-b | `DELETE /clusters/{id}/instances/{id}` | 用正确的 token 和 ID 请求,返回空 body(无 JSON),前端解析会失败 | ### P2 - 中 (Medium) | ID | 标题 | 发现者 | 页面/端点 | 描述 | |----|------|--------|-----------|------| | BUG-005 | Tags 专用端点缺失 | user-b | `GET /registries/{id}/repositories/{repo}/tags` | 端点未实现,返回纯文本 "404 page not found"。虽可通过 `/artifacts` 获取 tag,但 API 不完整 | | BUG-006 | 跨用户 namespace 部署时静默覆盖 | user-c | `POST /clusters/{id}/instances` | 用户请求部署到其他用户的 namespace 时,服务端静默使用自己的 namespace,返回 200 且无任何警告或提示 | | BUG-007 | Clusters Metrics API 缺失 | user-b | `GET /monitoring/clusters/{id}/metrics` | 监控页面可能需要的数据端点未实现(404) | | BUG-008 | Cluster Stats API 缺失 | user-b | `GET /clusters/{id}/stats` | 统计端点未实现(404) | | BUG-009 | Kubeconfig API 缺失 | user-b | `GET /clusters/{id}/kubeconfig` | kubeconfig 签发端点未实现(404) | | BUG-010 | "Launch" 按钮缺乏可访问性标识 | user-a | TagCard "Launch" | Chart 上的 "Launch" 按钮无 `aria-label`,与侧边栏 "Launch Instance" 导航项标签冲突,屏幕阅读器用户无法区分 | ### P3 - 低 (Low) | ID | 标题 | 发现者 | 页面/端点 | 描述 | |----|------|--------|-----------|------| | BUG-011 | API 响应格式不一致 | user-b | 列表 API | Clusters/Registries 返回裸数组,Instances 返回 `{ "instances": [...], "total": N }` 包装对象 | | BUG-012 | `/auth/me` 返回空的 token 字段 | user-b | `GET /auth/me` | 响应中包含 `"accessToken": ""` 和 `"refreshToken": ""` 空字段,复用了 login 响应 DTO 未清理 | | BUG-013 | 登录接口存在用户枚举漏洞 | security | `POST /auth/login` | 不存在用户返回 "user not found",存在用户返回 "invalid password",攻击者可枚举有效用户名 | | BUG-014 | 登录接口无速率限制 | security | `POST /auth/login` | 10 次连续请求全部返回 401,无 429 限流或锁定 | | BUG-015 | Nginx 版本信息泄露 | security | HTTP Headers | `Server: nginx/1.27.5` 暴露精确版本号 | | BUG-016 | CORS 配置过于宽松 | security | All API | `Access-Control-Allow-Origin: *` 允许任意跨域请求 | | BUG-017 | 缺少安全响应头 | security | All pages | 缺少 HSTS、X-Frame-Options、Content-Security-Policy 等 | | BUG-018 | `/health` 端点返回 SPA HTML | security | `GET /health` | 健康检查返回完整 index.html,非 JSON 状态响应 | --- ## 分类汇总 ### 前端 Bug | ID | 描述 | 严重度 | |----|------|--------| | BUG-001 | Launch 按钮无反应(核心功能阻塞) | P0 🔴 | | BUG-002 | SPA 路由空白页 | P0 🔴 | | BUG-010 | Launch 按钮缺少 aria-label | P2 🟡 | ### 后端 API Bug | ID | 描述 | 严重度 | |----|------|--------| | BUG-003 | DELETE 返回 404 | P1 🟠 | | BUG-004 | DELETE 空 body | P1 🟠 | | BUG-005 | Tags 端点缺失 | P2 🟡 | | BUG-007 | Metrics API 缺失 | P2 🟡 | | BUG-008 | Stats API 缺失 | P2 🟡 | | BUG-009 | Kubeconfig API 缺失 | P2 🟡 | | BUG-011 | 响应格式不一致 | P3 🔵 | | BUG-012 | auth/me 空 token 字段 | P3 🔵 | | BUG-018 | /health 返回 HTML | P3 🔵 | ### 安全/权限 Bug | ID | 描述 | 严重度 | |----|------|--------| | BUG-006 | Namespace 静默覆盖(安全但令人困惑) | P2 🟡 | | BUG-013 | 用户枚举(错误消息差异) | P3 🔵 | | BUG-014 | 无速率限制 | P3 🔵 | | BUG-015 | Nginx 版本泄露 | P3 🔵 | | BUG-016 | CORS Origin: * | P3 🔵 | | BUG-017 | 缺少安全响应头 | P3 🔵 | ### 严重度分布 | 级别 | 数量 | |------|------| | P0 (Blocker) | 2 | | P1 (High) | 2 | | P2 (Medium) | 6 | | P3 (Low) | 8 | | **合计** | **18** | --- ## 测试通过项 ### 认证 - [x] 有效凭据登录 (admin + 所有 test-user) - [x] 无效凭据返回 401 - [x] 无 token 访问被保护 API 返回 401 - [x] 无效/篡改 JWT token 全部被拒绝 - [x] /auth/me 返回正确的用户信息 - [x] JWT payload 包含角色、权限、namespace ### Cluster / Registry API - [x] 集群列表正常返回 - [x] 集群健康检查正常 - [x] Registry 列表正常返回 - [x] 通过 artifacts 端点浏览 repository 正常 - [x] 无效 registry/repository 返回恰当错误 ### 权限隔离 - [x] GET /users 返回 403 (普通用户) - [x] POST /auth/register 返回 403 (普通用户) - [x] 用户无法访问其他用户的 workspace 资源 - [x] 用户无法部署到其他用户的 Kubernetes namespace - [x] 安全架构:核心认证/授权/脱敏/隔离控制均正确实现 ### 实例部署生命周期 - [x] 实例创建操作成功(pending-install) - [x] 实例状态正确追踪(pending-install → deployed) - [x] 实例删除正确转换状态(pending-delete → 消失) - [x] 实例列表按 clusterId 正确过滤 ### 安全测试通过项 - [x] XSS/SQLi 注入安全处理 - [x] 路径遍历攻击被阻止 - [x] JWT alg=none/无效格式被拒绝 - [x] 集群凭据和 Registry 密码脱敏显示 (••••••••) - [x] 自注册端点需认证 (401) --- ## 建议修复优先级 ### 立即修复 (P0) 1. **BUG-001**: 调查 Launch 按钮 onClick handler — TagCard 组件中 `onLaunch` prop 未正确传递给 LaunchModal,或 launch 状态 / artifactType 检查阻止了 modal 打开 2. **BUG-002**: 检查 React Router `` 组件和 SPA 的 index.html 配置,确保旧路由正确重定向 ### 尽快修复 (P1) 3. **BUG-003/004**: InstanceHandler.Delete 应返回 202 Accepted + `{"status":"deleting"}` 而非 404+空 body ### 短期修复 (P2) 4. 实现 `/metrics`, `/stats` 等缺失 API 5. Launch 按钮添加 `aria-label` 属性 6. Namespace 覆盖时返回警告或 403 ### 安全加固 (P3) 7. 登录错误消息统一为 "Invalid username or password" 8. 实现速率限制 9. Nginx 安全加固:`server_tokens off` + 安全响应头 10. CORS 收紧为具体域名 11. 修复 `/health` 端点 12. 统一 API 响应格式