OneNav 6.02 :Bug 与待完善功能清单
日期:2026-10-04 | 范围:父主题 OneNav 6.02 全量 PHP(根目录模板、inc/、iopay/、assets/js)
一、结论概览
严重度
数量
说明
高
1
分类 Feed 分页规则 bug(影响 SEO/收录)
中高
2
上传权限过宽;卡密前台入口残缺
中
3
提现无审批流;app 端点半成品;通知接口空壳
低
若干
PHP8 isset 隐患、时区混用、遗留 TODO 等
已修复(6.02 相对旧版)
4
go.php 重写、测试邮件中继移除等(见第六节)
二、已确认 Bug(按严重度排序)
BUG-1【高】分类 Feed 分页 rewrite 规则写错变量
位置:inc/redirect-canonical.php:293-294
现象:分类 Feed 的分页 rewrite 规则中 =$matches[1],应为 $matches[2] / $matches[3](对照同函数 286-287 行新分页格式的正确写法可确认是复制粘贴遗漏)
影响:/category/xxx/feed/page/2 类地址无法正确解析到对应分页,Feed 分页 404 或内容重复,影响搜索引擎对 Feed 的抓取
修复建议:将两处 $matches[1] 改为 $matches[2]、$matches[3]
备注:子主题 inc/redirect-canonical.php 已自带修复版,且会覆盖父主题同名规则
BUG-2【中高】附件上传权限校验被注释,任意登录用户可上传
位置:inc/action/ajax-attachments.php:148-168
现象:io_upload_user_attachments() 有登录校验 + nonce 校验,但 current_user_can('upload_files') 被注释掉(165-168 行)
影响:订阅者等最低权限角色也能向媒体库上传附件。虽经 io_prepare_attachment_filename 白名单过滤文件类型,不存在任意文件上传,但媒体库可被灌垃圾、占磁盘
关联:同文件分片上传链路还缺 nonce、分片数无上限(子主题 module-patches merge_chunks 补丁已在挡)
修复建议:恢复权限校验,或按角色白名单放开(如 edit_posts 以上)
BUG-3【中高】卡密兑换前台仅支持余额卡,积分卡/VIP 卡无入口
位置:iopay/action/ajax-pay.php:155-188(第 176 行硬编码 'balance')+ iopay/assets/js/pay.js:15-24(前端 action 固定为 user_redeem_balance_cardkey)
现象:6.02 新增的卡密体系里,核心函数 io_cardkey_redeem()(iopay/functions/iopay-cardkey.php:306-388)本身完整支持 balance/points/vip 三种卡的兑换与发放,后台也能生成三种卡;但前台唯一兑换端点写死 expect_type='balance',用户拿到积分卡/VIP 卡在前台无处可用
影响:积分卡、VIP 卡成为死库存,只能后台手工处理
修复建议:前端卡密支付分支增加卡类型选择或按卡号前缀自动路由,后端端点按传入类型分发
BUG-4【中】提现功能无审批流,申请即扣款
位置:iopay/admin/functions/f-withdraw.php:104-114(查询仅按 status=0/1 过滤)、iopay/configs/ipc-balance.php:24-60(开关与费率配置)
现象:用户发起提现立即扣减余额,后台仅能事后标记打款/退回,没有"申请→审核→打款"的冻结审批环节
影响:管理员无法在打款前拦截异常申请;退回依赖手工操作
修复建议:增加"冻结金额"中间态,或至少提供申请阈值与频率限制
备注:站方若在意此点,可在子主题恢复独立提现模块(此前已下线,代码可从版本库找回)
BUG-5【中】统一通知接口 io_notify_user 是空壳
位置:inc/functions/notice.php:134-145
现象:父主题提供 io_notify_user() 作为统一通知入口,但函数体为空,全主题无人调用
影响:依赖它做站内信/邮件通知的功能全部静默失效
备注:子主题 module-notify 已将其真正实现(投稿审核、资产变动、VIP 变更、新粉丝四类事件),此问题已被站方覆盖
BUG-6【中】app 相关 AJAX 端点标注"待完善"且对游客开放
位置:inc/action/ajax-app.php:12-15(// TODO:待完善)、153-170 行(app_save / app_draft / app_pay 注册 wp_ajax_nopriv_* 匿名端点;165-170 行未判 isset 直接取 $_REQUEST['post_id'] / $_REQUEST['id'])
影响:半成品功能 + 匿名可触达 + PHP8 未定义下标告警三重问题叠加
修复建议:若不使用 app 功能,直接关闭;若使用,补齐权限与参数校验
三、半成品与待完善功能(TODO 清单)
#
位置
内容
状态
T1
inc/functions/io-cap.php:99-119(102 行 TODO)
角色能力框架已有 io_get_cap_roles() 读取,但角色能力编辑界面未构建,后台无法可视化分配能力
半成品
T2
inc/functions/io-home.php:286-317
// TODO 权限判断重新设计——首页菜单渲染的 purview 权限过滤逻辑待重构
待重构
T3
inc/action/ajax-app.php:12
// TODO:待完善,见 BUG-6
半成品
T4
inc/functions/io-user.php:1285
移动端下拉菜单里的社交登录按钮被注释,仅保留 PC 端入口
待完善
T5
inc/functions/io-checkin.php
每日签到无补签机制;连签数据存 usermeta 单键,无法追溯历史日历
可选增强
四、质量隐患(低危,暂不影响使用)
PHP8 未判 isset 直接取超全局/数组下标:inc/action/ajax-app.php:165-170 等多处,PHP8 下产生 Warning 刷屏
签到时区口径混用:inc/functions/io-checkin.php:95-125 用 current_time('Ymd') 与 date('Ymd', strtotime('-1 day', current_time('timestamp'))) 混算,站点时区为 UTC 以外时"昨天"边界有偏移风险;并发防重复有 add_user_meta(..., true) 唯一插入兜底,重复签到风险低
go.php 双重解码面:go.php:76-95 支持 base64 传参并再次走 io_go_safe_target() 白名单(esc_url_raw 仅放行 http/https),未发现开放重定向绕过,但 base64 通道让日志审计变难
AI AJAX 误报澄清:inc/functions/ai/ai-ajax.php 的 io_ai_ajax_resolve_generator() 虽带 nonce 缺失的 phpcs 标注,但所有端点(io_ai_generate / io_ai_finish_job / io_ai_test_connection)统一在入口做了 check_ajax_referer + current_user_can(65/67/84/122/124/147/149 行),已核实非问题
五、6.02 相对旧版已确认修复(供对照,非问题)
go.php 全面重写:io_go_safe_target() 白名单 + referer 校验 + XSS 转义,覆盖旧版全部已知弱点
测试邮件接口:wp_ajax_nopriv_test_mail 已移除(旧版可被游客当邮件中继,域名有被拉黑风险)
腾讯验证码:captcha.js 改为按需 $.getScript 加载 TCaptcha.js,功能闭环
归属地上报:io_set_country nopriv 钩子已废弃