2.4 KiB
2.4 KiB
Plan — vr-shopxo-plugin 安全评估 + 票务链路审计
版本:v2.0 | 日期:2026-05-26 | Agent:council/SecurityEngineer
Round 2 安全评估更新
新增发现:P3 XSS — $goods['content'] 未转义
文件:ticket_detail.html:75
<?php echo $goods['content']; ?> // ← admin-rich-text,直接输出
ShopXO 富文本编辑器输出。管理员可注入恶意 JS。仅管理员可编辑,风险范围有限。
修复:改为 <?php echo htmlspecialchars($goods['content']); ?> 或在后端对富文本做 XSS 过滤。
结论:P3(管理面可控),不影响票务安全链路。
Round 2 验证:QR 签名完整链路确认
| 步骤 | 代码 | 状态 |
|---|---|---|
signQrPayload 含 code 字段 |
BaseService.php:493 |
✅ 已确认 |
签名包含 iat + exp |
BaseService.php:493 |
✅ 30分钟有效 |
verifyQrPayload 验证过期 |
需检查验证端 | ⚠️ 待确认 |
BaseService::getVrSecret() 硬编码 |
BaseService.php:302 |
⚠️ P1(生产需确认.env) |
clearCache 在 $count > 0 后调用 |
TicketService.php:126 |
✅ 正确(但 $goodsId 未定义) |
Bug:ClearCache 调用时 $goodsId 未定义
文件:TicketService.php:126
SeatMapService::ClearCache(intval($goodsId)); // $goodsId 未在作用域内定义
这是 onOrderPaid 中的 Bug,$goodsId 应从 $og['goods_id'] 获取。当前代码会传递 0,清除无效。
严重度:P3(不影响票务安全,但 seatmap 缓存不会被清除)
安全评估结论摘要
| # | 问题 | 严重性 | 状态 |
|---|---|---|---|
| S-1 | issueTicket() 并发竞态(无悲观锁) | P0 建议 | 建议加唯一索引 (order_id, seat_info) |
| S-2 | QR Secret 硬编码 fallback | P1 | 需确认生产环境 .env 配置 |
| S-3 | FOR UPDATE SKIP LOCKED 概念混淆 | P2 | 防超卖依赖ShopXO原子UPDATE已有效 |
| S-4 | onOrderPaid 无事务包装 | P2 | 可接受(有幂等保护) |
| S-5 | $goods['content'] XSS(admin可控) |
P3 | 管理面风险,建议转义 |
| S-6 | $goodsId 未定义导致 ClearCache 失效 |
P3 | Bug,不影响票务链路 |
无 P0 安全漏洞。支付链路整体安全,不应成为主攻方向阻塞项。
投票
议题:下一步主攻方向 投票:C(双线并行)(Round 2 确认,不变)