安全审计报告 (Security Audit Report)
项目名称: Enterprise Verification System
审计日期: 2025年12月8日
审计对象: 源代码文件 (PHP)
文档版本: v1.1 (含漏洞复现与攻击详解)
1. 概览 (Executive Summary)
本次代码审计发现系统存在多处高危漏洞。由于核心业务逻辑处理顺序错误,结合输入验证缺失,攻击者可通过组合利用(XSS + 权限绕过 + SQL注入)完全接管数据库或窃取敏感数据。
| 漏洞名称 |
风险等级 |
涉及文件 |
状态 |
| 权限绕过 (Authorization Bypass) |
高危 (Critical) |
cards.php |
未修复 |
| SQL 注入 (SQL Injection) |
高危 (High) |
database.php |
未修复 |
| 反射型跨站脚本 (Reflected XSS) |
中危 (Medium) |
cards.php |
未修复 |
| 认证逻辑缺陷 (Broken Authentication) |
中危 (Medium) |
verify.php, auth_check.php |
未修复 |
2. 漏洞复现与攻击详解 (Vulnerability Analysis & PoC)
2.1. 权限绕过 (Authorization Bypass)
- 位置:
cards.php (Line 37-56)
-
攻击原理:
管理员后台在验证用户是否登录(admin_logged_in)之前,就优先处理了 POST 请求(如导出、删除)。虽然代码中包含了 verifyCSRF() 检查,但这意味着系统的安全性完全依赖于 CSRF Token 的保密性,而非用户身份认证。
一旦攻击者获取了 CSRF Token(例如通过 XSS 漏洞读取,或利用会话固定漏洞),即可在不输入密码、不登录的情况下直接执行管理员操作。
-
复现步骤 (PoC):
- 假设攻击者拥有一个有效的
PHPSESSID 和对应的 csrf_token(可通过 XSS 获取)。
- 攻击者直接发送构造好的 POST 请求:
curl -X POST "http://target.com/cards.php" \
-b "PHPSESSID=攻击者会话ID" \
-d "csrf_token=泄露的TOKEN" \
-d "batch_export=1" \
-d "ids[]=1"
- 结果: 即使该会话未登录(
admin_logged_in 为空),服务器也会直接返回导出的敏感卡密文件。
2.2. SQL 注入 (SQL Injection)
- 位置:
database.php -> deleteApp($id)
-
攻击原理:
deleteApp 方法直接将变量 $id 拼接到 SQL 查询语句中。
$count = $this->pdo->query("SELECT COUNT(*) FROM cards WHERE app_id = $id")->fetchColumn();
由于 SQLite 支持堆叠查询(Stacking Queries)或子查询,攻击者可利用此漏洞执行任意 SQL 命令。
-
复现步骤 (PoC):
- 利用前述的“权限绕过”或登录后台。
- 发送如下 POST 请求触发删除应用操作,但在
app_id 中注入恶意 SQL:
POST /cards.php HTTP/1.1
...
Content-Type: application/x-www-form-urlencoded
csrf_token=有效TOKEN&delete_app=1&app_id=1 OR 1=1; --
- 结果:
- 如果是
1 OR 1=1,COUNT(*) 可能返回所有记录数,导致抛出异常,泄露数据库状态。
- 更严重的攻击(SQLite 特定):
app_id=0; DROP TABLE cards; --
这将导致 cards 表被直接删除。
2.3. 反射型跨站脚本 (Reflected XSS)
2.4. 认证逻辑缺陷与会话固定 (Broken Authentication)
- 位置:
verify.php
- 攻击原理:
- 会话固定: 登录成功后不刷新 Session ID。攻击者可以先访问网站获取一个 Session ID,诱导受害者使用该 URL(携带相同 Session ID)登录。登录后,攻击者即可使用原 Session ID 进入受害者账户。
- 逻辑漏洞:
verify.php 设置的 Session 变量不全(缺 expire_time 等),导致即使“登录成功”,auth_check.php 也会因为缺少字段而判定验证失败,用户体验极差且安全逻辑混乱。
3. 修复方案概览 (Fix Recommendations)
- 调整代码顺序:
在 cards.php 中,将 if (!isset($_SESSION['admin_logged_in'])) ... exit; 块移动到文件最上方(仅次于 session_start 和 require),确保所有 POST 处理都在登录检查之后。
- 参数化查询:
修改 database.php,所有含变量的 SQL 执行必须使用 $pdo->prepare("... ? ...")->execute([$var])。
- 输出编码:
在 cards.php 中输出 $_GET['q'] 时,使用 htmlspecialchars($_GET['q'])。
- 强化会话:
在 verify.php 验证成功后,添加 session_regenerate_id(true) 并补全所有 Session 字段。
|