2026-04-15 05:53:39 +00:00
|
|
|
|
# vr-shopxo-plugin Phase 2 — 后台管理开发计划
|
|
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
|
|
Phase 2 目标:完成后台管理页面开发,涵盖座位模板管理、电子票管理、核销员管理、核销记录查询,以及 Admin 控制器鉴权修复。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 安全研究方向(SecurityEngineer)
|
|
|
|
|
|
|
|
|
|
|
|
### R1: Admin 控制器鉴权风险
|
|
|
|
|
|
|
|
|
|
|
|
**背景**:Council 安全审议发现 P1 问题 —— Admin 控制器缺少统一鉴权机制,Phase 2 所有后台页面均受影响。
|
|
|
|
|
|
|
|
|
|
|
|
**Key Questions**:
|
|
|
|
|
|
- [ ] ShopXO 后台 admin 控制器统一鉴权入口在哪里?`AdminBaseController` 或中间件?
|
|
|
|
|
|
- [ ] Phase 2 新增的 Base 控制器(`app/common.php` 的 Base 类)是否已正确调用鉴权?
|
|
|
|
|
|
- [ ] 各子控制器(SeatTemplate / Ticket / Verifier)是否有遗漏的 public 方法暴露未授权访问?
|
|
|
|
|
|
- [ ] 鉴权失败后的跳转逻辑是否正确?是否存在认证绕过风险?
|
|
|
|
|
|
- [ ] 后台操作是否需要二次验证(如删除、核销等敏感操作)?
|
|
|
|
|
|
|
|
|
|
|
|
**优先级**:P0
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### R2: SQL 注入风险评估
|
|
|
|
|
|
|
|
|
|
|
|
**背景**:电子票导出、核销记录查询等涉及复杂 SQL,必须防范注入。
|
|
|
|
|
|
|
|
|
|
|
|
**Key Questions**:
|
|
|
|
|
|
- [ ] ShopXO 原生查询构造器(Db::table / Db::name)的参数绑定机制是否覆盖所有输入点?
|
|
|
|
|
|
- [ ] 日期范围查询、模糊搜索等动态构造场景是否存在拼接风险?
|
|
|
|
|
|
- [ ] IN() 子句的数组参数是否经过安全处理?
|
|
|
|
|
|
- [ ] 关联查询(join)中是否有注入向量?
|
|
|
|
|
|
- [ ] 是否有 ORM 之外的原始 SQL 执行需要审查?
|
|
|
|
|
|
|
|
|
|
|
|
**优先级**:P1
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### R3: XSS / CSRF 风险
|
|
|
|
|
|
|
|
|
|
|
|
**背景**:后台管理页面输出到管理端,但仍需防范存储型 XSS 和 CSRF。
|
|
|
|
|
|
|
|
|
|
|
|
**Key Questions**:
|
|
|
|
|
|
- [ ] 后台页面渲染时是否统一使用 htmlspecialchars 或框架转义?
|
|
|
|
|
|
- [ ] 富文本编辑(如座位模板名称备注)是否存在存储型 XSS?
|
|
|
|
|
|
- [ ] POST 请求是否均携带 CSRF Token?ShopXO 的 CSRF 保护机制是什么?
|
|
|
|
|
|
- [ ] JSON API 响应是否可能携带恶意脚本?
|
|
|
|
|
|
- [ ] 删除/核销等关键操作是否有 CSRF Token 保护?
|
|
|
|
|
|
|
|
|
|
|
|
**优先级**:P1
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### R4: 敏感操作审计日志
|
|
|
|
|
|
|
|
|
|
|
|
**背景**:核销操作、票务导出等属于高敏感操作,必须可追溯。
|
|
|
|
|
|
|
|
|
|
|
|
**Key Questions**:
|
|
|
|
|
|
- [ ] 是否需要新建 `vr_audit_log` 表记录关键操作?
|
|
|
|
|
|
- [ ] 核销记录是否需要记录操作人 IP、UA、设备指纹?
|
|
|
|
|
|
- [ ] 导出操作是否需要记录?谁、何时、导出内容摘要?
|
|
|
|
|
|
- [ ] 审计日志是否需要防篡改设计(如 hash chain 或 append-only 表)?
|
|
|
|
|
|
- [ ] ShopXO 是否有现有审计日志机制可以复用?
|
|
|
|
|
|
|
|
|
|
|
|
**优先级**:P2
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### R5: 水平越权风险(IDOR)
|
|
|
|
|
|
|
|
|
|
|
|
**背景**:核销员管理、电子票详情等场景存在横向越权风险。
|
|
|
|
|
|
|
|
|
|
|
|
**Key Questions**:
|
|
|
|
|
|
- [ ] 核销员详情/编辑接口是否校验当前用户所属机构/场馆?
|
|
|
|
|
|
- [ ] 电子票详情接口是否校验持票人身份?
|
|
|
|
|
|
- [ ] 核销记录查询是否仅返回当前核销员/机构的记录?
|
|
|
|
|
|
- [ ] 删除/编辑操作是否有归属校验(owner check)?
|
|
|
|
|
|
- [ ] 是否有测试用例覆盖常见的 IDOR 攻击向量?
|
|
|
|
|
|
|
|
|
|
|
|
**优先级**:P1
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 任务清单
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] **Task S1** — 审查 ShopXO 后台鉴权机制,确认 Phase 2 Base 控制器鉴权覆盖完整性 `[Pending]`
|
|
|
|
|
|
- [ ] **Task S2** — SQL 注入风险审计,覆盖所有 Phase 2 数据查询 `[Pending]`
|
|
|
|
|
|
- [ ] **Task S3** — XSS / CSRF 防护检查 `[Pending]`
|
|
|
|
|
|
- [ ] **Task S4** — 敏感操作审计日志设计 `[Pending]`
|
|
|
|
|
|
- [ ] **Task S5** — IDOR / 水平越权测试用例编写 `[Pending]`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 阶段划分
|
|
|
|
|
|
|
|
|
|
|
|
| 阶段 | 内容 | 负责 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| Draft | 资料收集、研究方向确认 | 所有成员 |
|
|
|
|
|
|
| Review | 代码实现审查、安全评审 | SecurityEngineer + Council |
|
|
|
|
|
|
| Finalize | 合并到 main、文档整理 | 所有成员 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Agent 任务分配
|
|
|
|
|
|
|
|
|
|
|
|
| Agent | 主要任务 |
|
|
|
|
|
|
|-------|---------|
|
|
|
|
|
|
| BackendArchitect | API 设计、权限模型、数据库查询 |
|
|
|
|
|
|
| SecurityEngineer | Admin 鉴权、注入/XSS、审计、IDOR |
|
|
|
|
|
|
| FrontendDev | UI 框架选型、ShopXO admin 风格适配 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 依赖关系
|
|
|
|
|
|
|
|
|
|
|
|
- Task S1(鉴权审查)需在 BackendArchitect 完成 API 设计初稿后进行交叉评审
|
|
|
|
|
|
- Task S2(SQL 审计)可与 BackendArchitect 的数据库设计并行
|
|
|
|
|
|
- Task S4(审计日志)依赖最终的数据模型设计
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 讨论结论
|
|
|
|
|
|
|
|
|
|
|
|
本轮为 Round 1 纯讨论,所有成员完成研究方向确认后,进入 Round 2 执行阶段。
|
|
|
|
|
|
|
|
|
|
|
|
**SecurityEngineer 立场**:研究方向已明确,5 个方向覆盖鉴权、注入、XSS/CSRF、审计日志、IDOR,优先级合理。建议进入执行阶段。
|
2026-04-15 06:00:20 +00:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 安全审计结果(Round 2 执行)
|
|
|
|
|
|
|
|
|
|
|
|
### R1 审计结论 — Admin 控制器鉴权 ✅ P0 已修复
|
|
|
|
|
|
|
|
|
|
|
|
**问题**:插件 `Base.php` 仅调用 `AdminService::LoginInfo()`,绕过了 ShopXO 完整鉴权链。
|
|
|
|
|
|
|
|
|
|
|
|
**ShopXO 鉴权层级**(3层):
|
|
|
|
|
|
1. `Common::__construct()` → SystemInit + ViewInit + `AdminService::LoginInfo()` + `PowerMenuInit` + CommonPluginsInit
|
|
|
|
|
|
2. `Base::__construct()` → `IsLogin()` (拦截未登录) + `IsPower()` (RBAC 权限节点校验) + `FormTableInit()`
|
|
|
|
|
|
3. 视图层 → 基于 `$this->left_menu` / `$this->admin_plugins` 渲染菜单
|
|
|
|
|
|
|
|
|
|
|
|
**修复方案**:
|
|
|
|
|
|
- 插件 `Base` 继承 `Common`(而非独立实现)
|
|
|
|
|
|
- 构造函数中手动调用 `IsLogin()` + `IsPower()` + `FormTableInit()`
|
|
|
|
|
|
- 子控制器的 `__construct()` 保持 `parent::__construct()` 调用方式(兼容)
|
|
|
|
|
|
|
|
|
|
|
|
**权限节点格式**:`plugins_vr_ticket-{controller}-{action}`
|
|
|
|
|
|
- 示例:`plugins_vr_ticket-seat_template-list`、`plugins_vr_ticket-ticket-export`
|
|
|
|
|
|
- 需在 ShopXO 后台「应用管理 → 票务插件 → 权限配置」中注册
|
|
|
|
|
|
|
|
|
|
|
|
**待确认阻塞项**:ShopXO 插件路由注册机制(`PluginsAdminService`)是否自动注册权限节点,或需手动配置。
|
|
|
|
|
|
|
|
|
|
|
|
### R2 初步审计结论 — SQL 注入 ✅ 风险可控
|
|
|
|
|
|
|
|
|
|
|
|
ThinkPHP 8 查询构造器使用参数绑定(`where()` / `whereIn()` / `like()`),已覆盖所有输入点。
|
|
|
|
|
|
- `Ticket::list()` 的 `like "%{$keywords}%"` — 安全(ThinkPHP 自动绑定参数)
|
|
|
|
|
|
- `SeatTemplate::list()` 同上
|
|
|
|
|
|
- `Verification::list()` 日期范围 `strtotime()` — 安全(转换为整数)
|
|
|
|
|
|
- 需 Review 待开发的 B1~B4 任务中是否存在原始 SQL 执行
|
|
|
|
|
|
|
|
|
|
|
|
### R3 初步审计结论 — XSS/CSRF ⚠️ 待 Review
|
|
|
|
|
|
|
|
|
|
|
|
- 控制器输出使用 `view()`(Twig 模板),默认转义,风险低
|
|
|
|
|
|
- `SeatTemplate::save()` 的 `seat_map` / `name` 字段存入 DB 前未做 XSS 过滤(存储型 XSS 风险在读取展示时)
|
|
|
|
|
|
- `Ticket::export()` / `Verifier::delete()` 等 POST 操作缺少显式 CSRF Token 检查
|
|
|
|
|
|
- 待 Review:ShopXO 的 `FormTableInit()` 是否内置 CSRF Token 验证
|
|
|
|
|
|
|
|
|
|
|
|
### R5 初步审计结论 — IDOR ⚠️ 发现 1 个 P1 问题
|
|
|
|
|
|
|
|
|
|
|
|
**Ticket::detail() P1 IDOR**:
|
|
|
|
|
|
```php
|
|
|
|
|
|
$ticket = \Db::name('plugins_vr_tickets')->find($id); // 任意 admin 可查看任意票
|
|
|
|
|
|
```
|
|
|
|
|
|
任何已登录 admin 可通过 `?id=X` 查看任意票详情(无 owner check)。需在 Task B2 中修复。
|
|
|
|
|
|
|
|
|
|
|
|
### Task S1 状态
|
|
|
|
|
|
|
|
|
|
|
|
- [x] **Task S1** — 审查 ShopXO 后台鉴权机制,确认 Phase 2 Base 控制器鉴权覆盖完整性 `[Done: SecurityEngineer]` ✅ P0 修复完成
|