| 项目 | 详情 |
|---|---|
| 审查日期 | 2026年5月19日 |
| 审查范围 | SQL注入、XSS、CSRF、认证授权、文件上传、支付安全、会话管理 |
| 发现问题数 | 47个 |
| 严重风险 | 12个 |
| 高风险 | 15个 |
| 中风险 | 14个 |
| 低风险 | 6个 |
文件:mcpsapi/controller/ChannelRebind.php:74
$cusername = $this->input('cusername','','trim');
$whereRaw .= ' origin_cusername="'.$cusername.'" or cusername="'.$cusername.'" ';
风险:用户输入 $cusername 直接拼接到 SQL 语句,可直接进行 SQL 注入攻击
相同问题位置:
guildapi/controller/ChannelRebind.php:74admin/controller/MemberRebind.php:97文件:api/controller/v2/Gift.php:206
->join('cy_libaoinfo a', 'll.infoid=a.id and ll.user_id="' . $this->input['userid'] . '"')
相同问题:api/controller/v1/Gift.php:108
文件:common/logic/Complex.php:166
$query = Db::query("SELECT SUM(total_amount*divide_point) as total FROM cy_polychannel_game_frozen WHERE `channel_id`={$channel_id} AND `status`=1");
多个文件使用 whereRaw 配合变量插值但未参数绑定:
api/controller/v2/User.php:918api/controller/v2/Gift.php:41service/WelfareService.php 多处admin/controller/Welfare*.php 多处guildapi/controller/*.php 多处mcpsapi/controller/*.php 多处// ❌ 错误写法
$whereRaw .= ' origin_cusername="'.$cusername.'"';
// ✅ 正确写法
$whereRaw .= ' origin_cusername=?';
$bindParams[] = $cusername;
文件:guildapi/controller/Login.php:98-103
}else{
$username = trim(input('get.username'));
$adminInfo = Db::name('nw_channel_admin')->where(['username' => $username])->find();
return $this->getdoLogin($adminInfo); // 直接登录,无密码验证!
}
风险:通过 GET 请求仅传 username 即可直接登录,无需密码
文件:common/logic/Auth.php:46-48
if ($findAuthRuleCount == 0) {
//return false;
return true; // ← 关键缺陷:未配置的路由默认放行
}
风险:任何未配置到菜单的控制器/操作都无需权限即可访问
文件:common.php:681-684
function mg_password($pw)
{
return md5(Env::get('ADMIN_PASS_PRE') . $pw);
}
风险:MD5 已不安全,易被彩虹表攻击
文件:admin/controller/Login.php:206-253
$id = input('post.id','','intval'); // id 从客户端获取
$adminModel->where(['id'=>$id])->update(['password'=>mg_password($new_password)]);
风险:未校验是否为当前登录用户,可修改其他管理员密码
文件:common/logic/Auth.php:33
if ($userId == 1) { return true; } // ID=1 直接跳过权限检查
相同位置:admin/controller/Rbac.php:33, admin/controller/User.php:40
文件:api/controller/Api.php:65-110
if (!$decryptStr || $api_debug == true) {
$this->input = input(); // 直接使用明文参数,绕过 AES 和签名验证
}
风险:通过请求头 qmapidebug: true 可绕过所有安全验证
文件:admin/controller/Login.php:110-121
文件:api/controller/Api.php:154,204
$mysgin = md5($arg); // MD5 签名强度不足
$str = openssl_encrypt($data, 'AES-128-ECB', $key); // ECB 模式不安全
位置:admin/view/ 下 652+ 处
以下模板直接输出未转义的用户输入:
<!-- admin/view/pay/list.html:189 -->
<input value="{$Request.get.orderid}">
<!-- admin/view/pay/list.html:195 -->
<input value="{$Request.get.username}">
<!-- admin/view/game_discount_v2/index.html:123 -->
<script>var initGameIds = '{$Request.get.game_id}'</script>
完整漏洞列表:
| 文件 | 行号 | 变量 |
|------|------|------|
| admin/view/pay/list.html | 134,189,195,201,208 | orderid, username, roleid, rolename, servername |
| admin/view/pay/index.html | 158,164 | orderid, username |
| admin/view/member/login_list.html | 73,80 | username, imeil |
| admin/view/member/bind_list.html | 55,63 | username, mobile |
| admin/view/member/index.html | 163,170 | m_nickname, m_username |
| admin/view/game_package/add.html | 165 | game_id |
| admin/view/welfare_grant/index.html | 81 | username |
文件:config.php:50
'default_filter' => '' // 全局过滤为空
仅 home/mobile 模块有过滤:
'default_filter' => 'trim,htmlspecialchars,addslashes,strip_tags'
admin/api/guildapi/mcpsapi 模块均无输入过滤
文件:common.php:109-122 — 定义了 HTMLPurifier 过滤函数,但从未被调用
| 检查项 | 状态 |
|---|---|
| CSRF Token 生成/验证 | ❌ 未实现 |
表单 __token 隐藏字段 |
❌ 未使用 |
| ThinkPHP 内置 CSRF 中间件 | ❌ 未启用 |
| 任何表单中的 CSRF 隐藏字段 | ❌ 完全没有 |
影响范围:所有 admin 后台表单均存在跨站请求伪造风险
文件:admin/controller/GamePackage.php:341
$result = move_uploaded_file($_FILES['data']['tmp_name'], iconv('UTF-8', 'GBK', $filename));
风险:
['ipa','apk']0777(第335行)相同问题:admin/controller/GameUpload.php:46
文件:home/controller/Member.php:1320-1352
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
$type = $result[2]; // 仅校验 base64 头部声明,不校验实际内容
风险:
RUNTIME_PATH 目录public/.htaccess 文件为空.htaccess 禁止 PHP 执行.php 文件可直接执行文件:admin/controller/GamePackage.php:313-316
.APK).apk.php)文件:service/PayService.php:575
$params['sign'] = $wxPay->MakeSign($params, '66052a198653943dbc6c8032f1a40a9c');
相同问题:
common/factory/pay/SywPay.php:107,203common/logic/PayCallback.php:182curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
位置:
common.php:373-374,884-885service/PayService.php:880-881,914-915common/library/WeixinPay.php:85-88文件:common.php:1475-1489
function formatFenToYuan($fen, $long = 2) {
return number_format($fen / 100, $long, '.', ''); // 浮点数除法可能丢失精度
}
文件:api/controller/v1/PayNotify.php:950-951
$payInfo = $payModel->where(['orderid' => $orderid])->find();
if ($payInfo['status'] == 1 && $payInfo['real_amount'] == $real_amount) {
return true; // 先查询再更新,存在并发风险
}
PayNotify.php:367 - md5($str . md5($key))文件:config.php:286-290
'secure' => false, // 允许 HTTP 明文传输
'httponly' => '', // JS 可读取 Cookie
文件:public/index.php:14, guildapi/controller/Guild.php:70
header('Access-Control-Allow-Origin: *'); // 允许任意来源
未设置以下安全头:
Content-Security-PolicyX-Frame-OptionsX-XSS-ProtectionX-Content-Type-OptionsStrict-Transport-Security文件:config.php:24
'app_debug' => Env::get('app_debug', true) // 默认开启
| 序号 | 问题 | 位置 |
|---|---|---|
| 1 | SQL 注入 - 用户输入直接拼接 | mcpsapi/controller/ChannelRebind.php:74 |
| 2 | SQL 注入 - JOIN 条件拼接 | api/controller/v2/Gift.php:206 |
| 3 | GuildAPI GET 免密登录 | guildapi/controller/Login.php:98-103 |
| 4 | 权限未注册规则默认放行 | common/logic/Auth.php:46-48 |
| 5 | 密码使用 MD5 哈希 | common.php:681-684 |
| 6 | Admin 模板 652+ 处 XSS | admin/view/ 多处 |
| 7 | 完全没有 CSRF 防护 | 全局 |
| 8 | 文件上传绕过框架 | admin/controller/GamePackage.php:341 |
| 9 | 硬编码支付密钥 | service/PayService.php:575 |
| 10 | SSL 证书验证禁用(51处) | common.php 等 |
| 11 | API 调试模式绕过验证 | api/controller/Api.php:65-110 |
| 12 | Base64 上传校验可绕过 | home/controller/Member.php:1320 |
| 序号 | 问题 | 位置 |
|---|---|---|
| 1 | 密码修改 IDOR 越权 | admin/controller/Login.php:206 |
| 2 | 硬编码超管 ID | common/logic/Auth.php:33 |
| 3 | SQL 注入 - Db::query 变量插值 | common/logic/Complex.php:166 |
| 4 | 上传目录 0777 权限 | admin/controller/GamePackage.php:335 |
| 5 | 金额精度问题 | common.php:1475-1489 |
| 序号 | 问题 | 数量 |
|---|---|---|
| 1 | whereRaw 未参数绑定 | 约 50+ 处 |
| 2 | 登录无暴力破解防护 | 1 处 |
| 3 | API 签名 MD5+ECB | 多处 |
| 4 | 缺少重放攻击防护 | 全局 |
| 5 | 订单竞态条件 | 1 处 |
| 6 | Cookie 配置不安全 | 全局 |
| 7 | CORS 过于宽松 | 2 处 |
| 8 | 安全响应头缺失 | 全局 |
| 9 | 全局输入过滤为空 | 1 处 |
| 10 | 上传目录无执行限制 | 全局 |
return false)// ❌ 错误
$whereRaw .= ' origin_cusername="'.$cusername.'"';
Db::query("SELECT * WHERE id={$id}");
// ✅ 正确
$whereRaw .= ' origin_cusername=?';
$bindParams[] = $cusername;
Db::query("SELECT * WHERE id=?", [$id]);
<!-- ❌ 错误 -->
<input value="{$Request.get.username}">
<!-- ✅ 正确 -->
<input value="{:escape($Request.get.username)}">
// ❌ 错误
return md5($prefix . $password);
// ✅ 正确
return password_hash($password, PASSWORD_DEFAULT);
// 验证
return password_verify($input, $hashedPassword);
<form>
{csrf_field()}
<!-- 或 -->
<input type="hidden" name="__token" value="{$Request.token}">
</form>
审查报告生成时间:2026年5月19日