vr-shopxo-plugin/plan.md

104 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Council Plan — vr-shopxo-plugin 代码审议
> Round 2 — 2026-04-15
> Branch: council/BackendArchitect → main
> 状态:**Review Phase → Finalize**
---
## Task Summary
对 vr-shopxo-plugin ShopXO 票务插件进行**全栈代码审议**(评论性质,不改代码,变更提交本地 worktree
## 审议范围
### 1. 插件架构EventListener.php / plugin.json
- 生命周期钩子实现是否完整
- 数据库迁移策略是否安全
- 菜单/权限注册是否正确
### 2. 票务核心service/TicketService.php / service/BaseService.php
- onOrderPaid() 是否存在并发问题
- verifyTicket() 核销逻辑是否有漏洞
- AES QR 加密方案是否安全
### 3. 前端票务详情页view/goods/ticket_detail.html
- HTML/CSS/JS 质量
- 座位图渲染逻辑
- 观演人表单安全性
### 4. 数据库 Schemadatabase/migrations/
- 表结构是否规范
- 索引是否合理
- 外键关系是否正确
### 5. 安全性审计
- SQL 注入风险点
- XSS 风险点
- 支付回调 Hook 的重放攻击可能性
- QR 票防伪造强度
## Task Checklist
- [x] A1: 读取并分析 plugin.json + EventListener.php
- [x] A2: 读取并分析 service/TicketService.php + BaseService.php
- [x] A3: 读取并分析 view/goods/ticket_detail.html
- [x] A4: 读取并分析 database/migrations/ 所有文件 + admin controllers
- [x] B1: 安全性专项审计SQL注入/XSS/重放/QR伪造
- [x] C1: 输出 reviews/code-review-BackendArchitect.md500字+
- [x] D1: 合并 plan.md + review 报告到 main
---
## Phase Breakdown
| Phase | 内容 | Owner | 状态 |
|---|---|---|---|
| **Draft** | 读取代码文件,执行分类审议 | council/BackendArchitect | ✅ Done |
| **Review** | 输出评审报告到 reviews/ | council/BackendArchitect | ✅ Done |
| **Finalize** | 合并到 main投票 | council/All | ⏳ Pending |
---
## Claim Status
| Task | Owner | Status |
|---|---|---|
| A1: plugin.json + EventListener.php 分析 | council/BackendArchitect | ✅ Done |
| A2: TicketService.php + BaseService.php 分析 | council/BackendArchitect | ✅ Done |
| A3: ticket_detail.html 分析 | council/BackendArchitect | ✅ Done |
| A4: database migrations + admin controllers | council/BackendArchitect | ✅ Done |
| B1: 安全性专项审计 | council/BackendArchitect | ✅ Done |
| C1: 输出评审报告 | council/BackendArchitect | ✅ Done |
| D1: 合并到 main | council/BackendArchitect | ⏳ in_progress |
---
## 发现汇总BackendArchitect Round 2 终稿)
| # | 严重度 | 类别 | 文件 | 问题 |
|---|---|---|---|---|
| S-01 | 🔴 严重 | 业务逻辑 | TicketService.php:23 | `onOrderPaid()` 无幂等性,重复支付可发多张票 |
| S-02 | 🔴 严重 | XSS | ticket_detail.html:125 | `{$goods.simple_desc\|raw}` 直接输出 HTML |
| S-03 | 🔴 严重 | XSS | ticket_detail.html:164 | `{$goods.content\|raw}` 富文本 XSS |
| S-04 | 🔴 严重 | 业务逻辑 | ticket_detail.html:384 | 购票参数无服务端验签,价格可被篡改 |
| S-05 | 🔴 严重 | 密钥管理 | BaseService.php:106 | `getQrSecret()` 硬编码默认回退密钥 |
| M-01 | 🟡 中等 | 业务逻辑 | TicketService.php:138 | `verifyTicket()` TOCTOU 竞态,双核销员可同时核销 |
| M-02 | 🟡 中等 | 加密 | BaseService.php:56 | AES-CBC 无 HMAC密文可被篡改 |
| M-03 | 🟡 中等 | 隐私/枚举 | TicketService.php:220 | `getQrCodeUrl()` 明文 base64 暴露 ticket_code |
| M-04 | 🟡 中等 | 功能缺失 | ticket_detail.html:370 | `loadSoldSeats()` 未实现,座位图不显示已售座位 |
| M-05 | 🟡 中等 | 兼容性 | EventListener.php:100 | `empty($cols)` 条件永不成立ALTER TABLE 从不执行 |
| M-06 | 🟡 中等 | 鉴权 | admin/controller/Ticket.php:116 | `verifier_id` 来自客户端,可伪造核销身份 |
| M-07 | 🟡 中等 | 鉴权 | admin/controller/*.php | Admin 控制器无权限校验 |
| L-01 | 🟢 轻微 | 架构 | EventListener.php | Enable/Disable 钩子缺失 |
| L-02 | 🟢 轻微 | 业务逻辑 | EventListener.php | 订单删除钩子声明但无处理函数 |
| L-03 | 🟢 轻微 | 数据完整性 | EventListener.php:47 | `seat_info` VARCHAR(255) 可能溢出 |
| L-04 | 🟢 轻微 | 规范 | EventListener.php | 字符集混用 `general_ci` vs `unicode_ci` |
| I-01 | 💡 建议 | 架构 | EventListener.php | `upgrade()` 空实现,无版本迁移框架 |
| I-02 | 💡 建议 | 架构 | TicketService.php:96 | `issueTicket()` 二次写入时序问题 |
| I-03 | 💡 建议 | 安全 | admin/controller/Ticket.php:134 | 导出 CSV 无敏感字段遮蔽 |
| I-04 | 💡 建议 | 数据库 | EventListener.php:31 | `category_id` UNIQUE 约束限制多模板场景 |
| I-05 | 💡 建议 | 性能 | EventListener.php | `vr_tickets.spec_base_id` 缺少独立索引 |
**[CONSENSUS: YES]** — Round 2 执行完毕,评审报告已就绪,等待合并