19 Commits
Author SHA1 Message Date
youpaishidifu 554ddd11bc 加固-12(P0-10): fracture 折率 0 折免费开卡封堵(N3 两端校验 + N4 死代码清理)
fracture 折率若为 0/负数,代理端金额 = price × num × fracture 恒 ≤0,
余额检查形同虚设,零余额代理可无限免费开卡/开商品(2024 引入的新业务风险 N3);
creatfidkey 中 N4 复制粘贴死代码(金额检查误写成第二次数量检查,永远不可达)
正是该隐患的源头。

修复(入库端 + 使用端双保险):
- admin/ajax.php addgrade:grade_present 必须为 >0 的数字,否则拒绝入库
- admin/ajax.php changegrade:mod=fracture 修改时同规则下限校验(防后台改出 0 折)
- agent/ajax.php creatfidkey:levelinfo 取出后 fracture<=0 直接拒绝
  (code=-5「代理等级折率配置异常」),堵住 0 折存量数据;
  同时删除 N4 死代码(误复制的数量检查,提示语为"卡密金额")
- agent/ajax.php buy_submit(商品购买):同位置同规则折率下限守卫

回归(P0-10 22 项全 PASS,8082 内置服务器):
- addgrade:0/-0.5/非数字 全部拒绝且未入库;0.85 正常
- changegrade:fracture=0/非数字 拒绝;0.9 正常落库
- 折率=0 存量等级:creatfidkey 拒绝(code=-5),无卡密生成;
  buy_submit 拒绝(code=-5)
- 折率=0.9 且余额 0:creatfidkey 余额不足被拒(code=-10);
  buy_submit 余额不足被拒(原 0 折下此处直接免费成功/下单)
- 有余额成功路径无回归:creatfidkey 正常生成 2 张、余额 100->98.2;
  buy_submit 正常下单,订单 paymoney=0.9(折率正确计入)
- 已知残留(另行排期):creatkey/creatfidkey/buyagent 的扣款与插入
  仍无事务(插入失败钱照扣,2019 遗留)
2026-10-10 13:26:45 +08:00
youpaishidifu 94403a1a06 加固-08(P0-05b): 登录哈希写回幂等化,同账号并行会话不被后续登录破坏
背景:P0-07 支付加固回归中发现——admin/agent 登录成功时无条件重新生成
bcrypt 哈希并覆盖 DB 密码列。同一账号第二次登录后,第一次会话的
$_SESSION[xx_password](存"存储值"设计)与 DB 新哈希不再相等,
checklogin 的 WHERE username AND password=会话 重校验失败,
首个会话的后续操作(支付、后台操作)被拒。P0-05 原意只应在"旧格式
惰性迁移"时写回新哈希,现已哈希的存储值重复登录不应再变。

修复(仅当存储值尚未为 bcrypt 时写回新哈希,否则沿用原值):
- admin/ajax.php 登录:$newhash = wq_is_hashed_password($result['password'])
  ? $result['password'] : wq_hash_password($_POST['password'])
- agent/ajax.php 登录:同上
- (API 用户登录 api/Communication.php 已有该条件判断,无需改动)
- 惰性迁移语义不变:旧 md5(admin)/ 旧明文(agent)仍登录一次即升级 bcrypt

回归(P0-05b 13 项全 PASS,8082 内置服务器):
- admin 双会话:第二次登录不改写 DB 哈希;两个会话 checklogin 均有效
- 模拟旧明文代理(DB 直接置明文):登录一次即升级为 bcrypt;
  第二次登录哈希不变;两个会话 checklogin 均有效
- P0-07 回归中的 yezf 双会话并发测试由本修复解锁(先前首会话因
  再登录被破坏而报"代理账号或密码不匹配")
2026-10-10 13:06:45 +08:00
youpaishidifu aaf5fe48c6 加固-07(P0-06): 封堵 SQL 注入面(动态列名白名单 + 裸拼值强类型化)
背景:多处 SQL 由用户输入拼接——update() 的动态键(mod)直接作列名入 SET 子句;
卡密/分类卡密批量 INSERT 手拼 SQL 值元组(insert_back_row 零转义);DelUse 删除
语句手拼 fid。列名注入与手拼值注入均可被利用篡改/破坏数据。

1. 列名注入(动态 mod 键):
   - function/function_core.php 新增 wq_is_db_field($name):仅允许 [A-Za-z0-9_]{1,64}
     合法 SQL 标识符,杜绝引号/空格/注释符进入列名
   - admin/ajax.php 四处 change* 动态更新加守卫(非法 mod 直接 die「不支持修改的字段」):
     * changegrade (sq_level)
     * changeuser  (sq_user)
     * changefid   (sq_fidlist)
     * changeagent (sq_agent)
   - 注:agent 侧 changeuser/changeagent 已有字段白名单(P0-05 已加 password 哈希),无需重复

2. 手拼 INSERT 值元组(creatkey / creatfidkey,admin+agent 双侧):
   - 卡密金额 sc_money:强制 is_numeric(),非法直接拒绝(money 会裸拼进 INSERT 与卡密串)
   - 分类 fid sc_fid:强制 (int) 整型化后再拼入(防多语句/注释符逃逸)

3. DelUse 删除语句(admin+agent 双侧):
   - fid 强制 (int) 整型化;agent 侧 aid 亦 (int) 化
   - 注入载荷如 "1 AND 1=1" 被截为 1,SQL 结构不再可被改写

回归(30 项全 PASS,8082 内置服务器):
- 各 change* 正常字段修改成功且 DB 生效;列名注入(price,x / 多语句 DROP 载荷)全部被拒,目标表完好
- creatkey 正常生成、余额正确扣除;money 注入载荷被 is_numeric 拒绝
- creatfidkey 合法 fid 正常生成;注入 fid 在 fid 查找即被拒(int 化后无命中)
- DelUse 注入 fid 被 int 化后正常执行(删 0 行),表结构完好
- 注:(int)"1; DROP..."=1(前导数字保留),(int)"'; DROP..."=0,载荷均无法逃逸 SQL 结构
2026-10-10 12:41:33 +08:00
youpaishidifu 24264cf320 加固-06(P0-05): 密码全部以 bcrypt 哈希入库,旧格式(明文/MD5)兼容并惰性迁移
背景:sq_user/sq_agent 密码明文入库、sq_admin 存 MD5;订单表 sq_trade.pass 明文在途;
找回密码 API 会把明文密码直接发邮件;日志记录明文密码。数据库泄露 = 全部账号密码泄露。

1. function/function_core.php 新增 3 个 helper(updateset 之后):
   - wq_is_hashed_password($v):判断存储值是否为新 bcrypt 哈希(60 长度 $2y$ 前缀)
   - wq_hash_password($plain):password_hash(PASSWORD_BCRYPT)
   - wq_verify_password($plain,$stored,$legacy):兼容 新 bcrypt / 旧明文(sq_user/sq_agent) / 旧 md5(sq_admin),
     哈希比对一律 hash_equals,恒定时间比较防时序侧信道

2. 所有落库点改为 bcrypt:
   - 用户开户漏斗 function/function_auth.php auth_add 入口幂等补哈希(上游已哈希则原样保留)
   - 代理开通漏斗 function/trade.inc.php type=4 代理落库前幂等补哈希
   - 下单点订单密码哈希入库:ajax.php(320/388/781)、agent/ajax.php(439) —— 订单表不再有明文在途密码
   - admin/ajax.php:addagent、addadmin、changeagent(mod=password)、changepassword 新密码
   - agent/ajax.php:开下级代理、changeuser(mod=password)、changeagent(mod=password)、changepassword 新密码
   - api.php:ChangePassword 写库
   - api/Communication.php 与 function/communication.php:用户登录校验成功后,旧明文惰性升级为 bcrypt

3. 所有校验点改为取行 + PHP 校验(不再 WHERE password=明文):
   - admin 登录(旧 MD5 兼容,成功即写回 bcrypt,session 与 DB 存同一新哈希保住 re-check 机制)
   - agent 密码登录(旧明文兼容,惰性迁移);agent token 登录 session 改存 DB 存储值
   - 根 ajax.php 续费 kt 密码校验(379/773)、卡密找回密码(1002)
   - api.php GetUserInfo 内联校验、getuserinfo() 校验(均带惰性迁移)

4. 找回密码改造(api.php RetrievePassword):
   密码已不可逆,原"邮件下发原密码"改为"重置为一次性随机新密码(bin2hex(random_bytes(6)))+ 哈希落库 + 仅邮件投递一次"

5. 日志/回传去明文:
   - admin 登录失败日志不再记录明文密码(改记账号)
   - admin getagentinfo 不再回传密码值(掩码 ********,经确认 UI 无回写风险)

6. 表结构:sq_admin.password varchar(33) -> varchar(255)(bcrypt 60 字符装不下)
   - wenquan_auth.sql 同步更新(新装库直接可用)
   - 已有库需执行:ALTER TABLE sq_admin MODIFY password varchar(255) NOT NULL;(本次本地库已执行)

回归(40 项全 PASS,8082 内置服务器 + 8081 nginx 双通道冒烟):
- API(c=api) 旧明文用户登录成功即升级 bcrypt;再登录幂等不错哈希;错密码 -205 被拒
- admin 旧 MD5 登录即迁移 bcrypt;再登录/错密码/日志无明文/checklogin 会话重校验均通过
- admin 新增管理员、改密(旧密码失效/新密码生效/恢复基线)
- admin 新增代理直接 bcrypt;getagentinfo 掩码;changeagent 改密哈希入库
- 旧明文代理登录即迁移 bcrypt;checklogin 通过;代理改密旧失效新生效
- admin 手工开通(funnel)明文 POST 直接存 bcrypt;API 登录新开通用户成功
- 注:测试应用 free 必须为 0(free=1 时 Login 入口直接放行,属产品设计,不走密码校验)

已知行为变化(记录):用户/代理列表按"密码"关键词搜索不再命中(存储已哈希,搜索本身即泄露向量,收紧);
列表中密码列显示 60 位哈希串而非明文;改密会使该账号现有会话失效需重新登录(与旧行为一致)。

api.php 为 2024 树中的旧入口(已被 api/Communication.php 取代),仍按同口径同步修了 4 处密码点防复活踩坑。
2026-10-10 12:25:52 +08:00
youpaishidifu c60e4ebc9b 加固-03(P0-02): 删除远程在线更新链(供应链 RCE 向量)
- admin/ajax.php: checkupdate / downloadupdatepacks / unzippacks 三个
  端点合并为统一禁用存根(返回 JSON "远程更新已禁用(安全加固)");
  原逻辑从作者第三方域 (download.wenquan6.cn / download.bwenquan.com)
  下载 zip 并解压到 Web 目录、再引导浏览器访问 install.php,
  攻击者控制该域即可向所有部署实例推送恶意代码(供应链 RCE)。
- 删除辅助函数 get_zip_originalsize() 与 getFile()(仅更新链使用)。
- admin/html/welcome.html 与 admin/welcome.html: 移除"检查系统更新"
  按钮及 function update() 整段 AJAX 链,替换为静态说明文案。
- admin/ajax.php: HTTP_USER_AGENT 比较改用 ?? 回退,消除无 UAgent
  客户端触发的 Notice(UAgent 会话锁定行为保持不变)。

验证: php -l 通过;登录态调用三端点均返回禁用 JSON;
UAgent 锁定对无 UAgent 客户端正确拒绝(code:-3)。
2026-10-10 11:21:25 +08:00
youpaishidifu 6669f4bc9c 加固-01/02: CWD 无关 include 改造 + UEditor 全入口鉴权 (P0-01)
A. 相对路径 include/require 全量改写为 __DIR__ 基址
   - 修复 nginx+fastcgi 下 php-cgi 继承启动目录 CWD (D:\phpstudy_pro\COM)
     导致 require '../function/...' 相对路径 include 全部失效;
     28 文件 101 处统一改为 __DIR__ 绝对基址,任意 Web 服务器行为一致。
   - 补齐带括号/缺斜杠漏改的 13 处 (controller.php、epay lib、
     payment.php、notify_url.php、return_url.php)。
   - function/config.inc.php 增加 config.local.inc.php 本地覆盖机制
     (该文件加入 .gitignore 不入库),仓库默认配置保持中立。

B. UEditor 后台入口安全加固 (P0-01)
   - admin/php/controller.php 全部 action 前置管理员会话校验
     (admin_username + admin_password),匿名无法上传/抓取/列目录/读配置。
   - 禁用远程图片抓取 catchimage (SSRF 向量),删除 action_crawler.php。
   - 上传/列表白名单剔除 .exe/.dll/.iso/.cab/.swf。
   - Uploader: 移除 iconv('unicode') Windows 告警行;
     getFileInfo/action_list 的 URL 拼接增加 REQUEST_SCHEME 回退。

验证: 匿名访问全部 action 返回未授权;登录态上传成功且 URL 正确;
catchimage 已禁用;JSON 合法;全量 php -l 0 错误;
nginx(8081) 与内置服务器(8082) 双通道回归通过。
2026-10-10 11:10:29 +08:00
温泉 64fe1116be Update welcome.html 2024-08-09 14:16:51 +08:00
星梦 1b5be6e041 Update ajax.php
修复管理员后台无法删除已使用卡密的BUG
2021-11-03 18:23:53 +08:00
小槑 321e15a38b Update login.html 2021-08-05 21:10:42 +08:00
xiaodaii fc667b7f31 修复vaptcha验证 2021-07-20 13:43:34 +08:00
xiaodaii 656eac7472 开通id显示错误 2021-06-23 22:29:21 +08:00
温泉 779fa38fda 修复后台首页跳转问题 2021-05-12 01:19:48 -05:00
温泉 877fc29d00 修复token登录报错的bug 2021-01-28 00:13:45 +08:00
温泉 714fae48ef 修复token登录后台无效的bug 2021-01-28 00:12:15 +08:00
温泉 cc7f47c359 修复Token密钥登录 2021-01-18 09:18:41 +08:00
wenquan 7fcb73c8c9 修复BUG 2020-09-06 13:26:03 +08:00
wenquan 8303aa4fc9 修复后台付款设置数据无法加载问题 2020-04-15 19:15:03 +08:00
wenquan e7b324a3d8 修复添加授权报错 2020-04-15 17:06:30 +08:00
温泉 ed35810923 Initial commit 2019-12-09 10:23:56 +08:00