29 Commits
Author SHA1 Message Date
youpaishidifu a688a24993 加固-10(P0-08): get_real_ip 全角竖线正则 bug——XFF 私有网段过滤一直未生效
function/function_core.php:159 的正则 /^(10│172.16│192.168)./ 中分隔符为
全角竖线 │(U+2502),对 ASCII IP 永远匹配不上,「跳过私有网段」逻辑
形同虚设:X-Forwarded-For 取到的总是客户端可自填的首项。后果是
IP 记录(sq_log_* 各表 IP 列)与基于 IP 的校验(如 API bindip 绑定)
可被 XFF 头伪造绕过。

修复:全角 │ 改为 ASCII 竖线 |(保留原网段清单 10/172.16/192.168,
不扩大行为面),原处注释说明原因。

回归(5 项全 PASS,CLI 直接驱动 get_real_ip):
- XFF [10.1.1.1, 8.8.8.8] -> 8.8.8.8(跳过私有,取首个公网)
- XFF [172.16.5.5, 192.168.1.1, 9.9.9.9] -> 9.9.9.9
- XFF [1.2.3.4] -> 1.2.3.4
- XFF 全私有 / 无 XFF -> 回退 REMOTE_ADDR
2026-10-10 13:08:44 +08:00
youpaishidifu e6f6188ab8 加固-09(P0-07): 支付加固——Host 头投毒、卡密/代理余额原子核销、epay 库 PHP8 致命、回调落库幂等
1. Host 头投毒(R8):payment.php 的回调/跳转 URL 原用 $_SERVER['HTTP_HOST']
   拼接,被污染的 Host 头可使 ePay notify/return 回调指向攻击者域名
   - function/function_core.php 新增 wq_site_base_url():host 优先取配置
     weburl 的 scheme+host 部分(配置由管理员维护,非攻击面),仅配置缺失
     时回退 HTTP_HOST;路径取当前请求挂载目录并归一化 Windows dirname 的
     反斜杠(兼容子目录部署)
   - payment.php 免费订单跳转、czkm/yezf 支付成功跳转、mqyturn 的
     notify/return 回调 URL 全部改用该 helper

2. 卡密/代理余额原子核销(双花消除):payment.php 的 czkm(卡密)与
   yezf(代理余额)原为「读取-校验-写回」,并发下同一卡密/余额可被
   重复扣减
   - 订单占用:条件 UPDATE(WHERE status='1'),affected_num()==0 即
     中止,防同订单并发重复支付
   - 卡密核销:UPDATE ... WHERE kami=? AND status='1' AND lastmoney>=?
     ,前置条件并入 WHERE;affected_num()==0 时回滚订单占用并提示重试
   - 代理余额:UPDATE ... WHERE status='1' AND money>=? 同理
   - 顺带修复 yezf 原 bug:allspend 只读进内存从未落库,现随余额
     原子累加

3. epay 库 PHP8 致命(R10):pay/epay/lib/epay_core.function.php
   - 两处 get_magic_quotes_gpc()(PHP8 已移除,调用即致命)改为
     function_exists 守卫
   - createLinkstringUrlencode 的 count($arg)(对字符串,PHP8 TypeError)
     改为 strlen($arg)-1(与 PHP7 下实际行为 substr(0,-1) 等价)
   - 已在 PHP 8.2 实测:两函数正常拼接/验签准备,无致命

4. pay/epay/notify_url.php / return_url.php:
   - 移除 notify_url.php 中用未定义 $lastmoney/$allspend 更新代理表的
     语句(PHP7 下 null 隐式转空串,回调时把代理余额与 allspend 清零;
     与 return_url.php 的既有行为对齐)
   - 订单状态落库改为条件 UPDATE(WHERE status='1'),并发回调重复
     落库防护;status=2 分支保持幂等 success
   - return_url.php 对称条件化

回归(P0-07 全 PASS,8082 内置服务器 + 8081 nginx 双通道冒烟):
- 免费订单/czkm/yezf 跳转 URL 全部使用配置 host;Host:evil.example.com
  投毒无效
- czkm 正常核销、余额不足拒绝;双进程并发两订单恰好一个成功,
  卡密余额恰扣一次(无双花),核销日志 +1
- yezf 正常扣减 100->70;并发双订单恰好一个成功,余额 70->30 只扣
  一次,allspend 只累加一次
- epay 库 PHP 8.2 下 createLinkstring / createLinkstringUrlencode 无致命
- 注:本地内置服务器为单 worker,并发请求实际串行处理;双花消除的
  保证来自 WHERE 原子前置条件(真实多 worker 并发下亦至多一个
  UPDATE 满足条件)
2026-10-10 13:07:10 +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 347af5537a 加固-04(P0-03): api/monitor.php 监控脚本鉴权 + 修复补单逻辑
- 增加鉴权:监控调用须带 ?key=monitor_key;密钥首次调用时自动生成
  (64hex,持久化到 sq_config setname='monitor_key',setname.inc.php
  增加种子行),hash_equals 校验,不匹配返回 403。杜绝匿名触发
  补单/清库。key 可通过 SELECT setvalue FROM sq_config WHERE
  setname='monitor_key' 获取,配置到 cron/监控服务。
- 修复 if(!!$result = select_limit_row(...) && count(...) > 0)
  运算符优先级断逻辑:拆为先取值再判断。
- 修复未定义变量 $tradeno(原 update 条件引用了从未赋值的 $tradeno)。
- trade_do 补单改为仅在状态 2->3 翻转成功(影响行数>0)时执行;
  影响行=0(已被先行进程完成)则跳过,防并发/重复补单。
- 修复 sq_apps 空表时 !array() 为真 导致误报"获取应用信息发生错误"
  (改为 false === 判断)。
- 结尾输出 JSON 结果(log/error),便于监控服务核对。

验证: 无key/错key 均 403;正确key 200;构造 status=2 测试订单,
首跑补单(agent 余额 100->110,trade 2->3),二跑无重复补单。
php -l 通过。
2026-10-10 11:32:56 +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
温泉 b8a0224e93 Update ver.inc.php 2024-08-09 14:18:39 +08:00
温泉 ef9b972af5 Update ver.inc.php
Update Version To 12.12
2024-07-30 16:45:28 +08:00
温泉 ea751a3cf9 Merge pull request #18 from xiaodaii/main
修复BUG
2024-07-18 10:14:07 +08:00
xiaodaii 299b91c8f9 卡密余额充值会创建两个账户 2022-08-06 18:22:35 +08:00
温泉 4ac3576071 Update ver.inc.php 2021-08-21 11:34:44 +08:00
xiaodaii acc6e1f88d 在线开通显示卡密不存在,续上次未考虑问题 2021-07-26 12:35:01 +08:00
xiaodaii fc667b7f31 修复vaptcha验证 2021-07-20 13:43:34 +08:00
xiaodaii 8ab40ab9a4 开通ID显示错误 2021-06-23 22:37:48 +08:00
xiaodaii 656eac7472 开通id显示错误 2021-06-23 22:29:21 +08:00
unknown 1ebd8d374e 修复人机验证的VID被固定问题 2020-09-09 18:03:52 +08:00
unknown 9495b56d1d 修复检查绑定开通时候没验证应用的BUG 2020-09-09 17:55:36 +08:00
wenquan 6b216086a3 将邮件发送方式改为本地邮件发送 2020-09-06 13:46:57 +08:00
温泉 332a01b5f3 修复获取用户IP导致的报错问题 2020-05-01 14:20:41 +08:00
温泉 053c46ffb7 删除各类不必要报错提示 2020-04-17 13:34:32 +08:00
wenquan 53d8b4e362 修复获取客户端IP报错的问题 2020-04-15 17:10:55 +08:00
wenquan 4f9a252e3b 优化数据库连接错误提示 2020-04-11 17:53:38 +08:00
wenquan 40db18262c 删除授权系统和取消忽略数据库配置文件 2020-04-11 17:48:03 +08:00
温泉 b711c17bd2 修复数据库插入数据BUG 2019-12-10 23:31:32 +08:00
温泉 d6006670ef 修复获取应用信息失败问题 2019-12-10 23:31:07 +08:00
温泉 3c4d572a19 修复数据插入BUG 2019-12-10 23:10:32 +08:00
温泉 e43e754145 修复插入数据问题 2019-12-10 22:50:13 +08:00
unknown 75963ae90f 修复部分情况下数据模块报错 2019-12-09 15:59:49 +08:00
温泉 ed35810923 Initial commit 2019-12-09 10:23:56 +08:00