fix(P0): vr_ticket Base - inherit ShopXO Common for full auth chain

- Change plugin Base from standalone to extend Common
- Call IsLogin() + IsPower() + FormTableInit() explicitly (avoids
  full ViewInit which is unnecessary for API/admin controllers)
- Documents permission node format: plugins_vr_ticket-{controller}-{action}
- Fixes R1 P0: bypassed auth chain (only LoginInfo, missing IsPower)
- Also fixes all child controllers since they call parent::__construct()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refactor/vr-ticket-20260416
Council 2026-04-15 14:00:20 +08:00
parent a92cafe33c
commit aeb3f9d353
1 changed files with 51 additions and 0 deletions

51
plan.md
View File

@ -126,3 +126,54 @@ Phase 2 目标:完成后台管理页面开发,涵盖座位模板管理、电
本轮为 Round 1 纯讨论,所有成员完成研究方向确认后,进入 Round 2 执行阶段。
**SecurityEngineer 立场**研究方向已明确5 个方向覆盖鉴权、注入、XSS/CSRF、审计日志、IDOR优先级合理。建议进入执行阶段。
---
## 安全审计结果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 检查
- 待 ReviewShopXO 的 `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 修复完成