
Php Auth Config Audit
- 11 installs
- 1.6k repo stars
- Updated July 19, 2026
- wgpsec/aboutsecurity
Helps with security tasks during AI-assisted development.
About
php-auth-config-audit is a Claude Code skill for security. It helps solo builders move faster with AI-assisted coding.
- php-auth-config-audit
- Security
- AI-coding skill
Php Auth Config Audit by the numbers
- 11 all-time installs (skills.sh)
- Ranked #1,657 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill php-auth-config-auditAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 11 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | July 19, 2026 |
| Repository | wgpsec/aboutsecurity ↗ |
What it does
Helps with security tasks during AI-assisted development.
Files
PHP 认证配置与逻辑类漏洞源码审计
本 skill 聚焦源码层面的认证、授权、配置、密码学和业务逻辑缺陷。运行时利用(如 JWT 伪造、条件竞争脚本)属于对应黑盒 exploit skill 范畴。
深入参考
- 5 类风险的危险模式 / 安全模式代码对比 / 检测方法 → references/auth-config-patterns.md
---
5 类风险速查表
| 类型 | 典型模式 | 危险信号 | 严重度 |
|---|---|---|---|
| 认证绕过 | 硬编码凭据、== 弱比较、JWT algorithm none | 登录/令牌验证逻辑 | Critical-High |
| 授权失控 | IDOR 直接引用、缺少 ownership 检查、中间件跳过 | 资源访问无权限校验 | High-Critical |
| 安全配置 | display_errors=On、CORS *、调试模式残留 | 信息泄露/跨域滥用 | Medium-High |
| 密码学误用 | md5($pass)、ECB 模式、硬编码密钥 | 密码存储/加解密逻辑 | High-Critical |
| 业务逻辑 | 竞争条件、支付金额可控、状态机跳步 | 交易/库存/状态流转 | High-Critical |
认证审计要点
- 硬编码密码/API Key: 搜索
password/secret/api_key/token赋值为字面量字符串的位置 - 弱比较:
==对比密码/token 导致类型混淆("0e123" == "0e456"为 true),必须使用===或hash_equals - JWT 缺陷: algorithm confusion(RS256→HS256)、签名未验证、
alg:none接受、密钥泄露、kid参数注入 - Remember Me: token 是否可预测(
md5(username.time()))、是否绑定用户/设备 - 密码重置: token 可预测性、token 是否绑定目标用户、是否有过期机制
授权审计要点
- IDOR:
$_GET['id']直接查询无WHERE user_id=归属检查,对象引用可水平篡改 - 路由级 vs 函数级权限: 中间件挂载范围是否完整覆盖、是否存在未保护的路由
- 中间件跳过: 路由分组遗漏、
withoutMiddleware滥用、OPTIONS 预检绕过 - 水平越权 vs 垂直越权: 水平 — 同角色访问他人资源;垂直 — 低权限访问高权限功能
配置审计要点
- 错误暴露:
display_errors=On+error_reporting=E_ALL泄露路径/SQL/栈信息 - CORS:
Access-Control-Allow-Origin: *配合Allow-Credentials: true允许任意源携带凭据 - 调试模式: Laravel
APP_DEBUG=true、ThinkPHPapp_debug、自定义DEBUG常量残留 - 安全头缺失:
X-Frame-Options、Content-Security-Policy、X-Content-Type-Options未设置
密码学审计要点
- 弱哈希:
md5($pass)/sha1($pass)用于密码存储,应使用password_hash(PASSWORD_BCRYPT) - ECB 模式: 确定性加密,相同明文产生相同密文,可分析推断内容
- 硬编码密钥:
KEY/IV/SECRET写死在源码中,搜索openssl_encrypt/mcrypt_*调用的密钥来源 - 弱随机数:
mt_rand/rand/uniqid用于生成安全令牌,应使用random_bytes/random_int
逻辑审计要点
- 竞争条件: 余额/库存先查后减无事务/无锁(SELECT→UPDATE 无
FOR UPDATE) - 支付金额篡改: 金额从客户端传入而非服务端计算、缺少签名验证
- 状态机跳步: 订单状态从"待支付"直接跳到"已发货",缺少状态转换合法性校验
- 批量操作无限制: 无频率限制/无数量上限,可被滥用进行批量操作
检测清单
- [ ] 硬编码凭据搜索已完成(password/secret/key/token/api_key)
- [ ] 所有
==比较密码/token 的位置已标记 - [ ] JWT 签名验证逻辑已审查(algorithm、密钥来源、kid)
- [ ] IDOR 风险点已检查 ownership 校验
- [ ] 路由权限覆盖完整性已验证
- [ ] php.ini / 框架配置安全基线已对照
- [ ] 密码存储方式已确认(password_hash vs md5/sha1)
- [ ] 加密密钥管理方式已审查(硬编码 vs 环境变量/密钥管理)
- [ ] 竞争条件敏感操作已检查事务/锁机制
- [ ] 支付/交易流程的金额来源和签名验证已确认
PHP 认证配置与逻辑类漏洞审计模式参考
5 类风险的危险代码 / 安全代码对比 + 检测方法。
---
1. 认证绕过
1.1 硬编码凭据检测
grep -rn "password\s*=\s*['\"]" --include="*.php"
grep -rn "secret\s*=\s*['\"]" --include="*.php"
grep -rn "api_key\s*=\s*['\"]" --include="*.php"
grep -rn "MYSQL_PASSWORD\|DB_PASS\|DB_PASSWORD" --include="*.php" --include="*.env"// 危险 // 安全
if ($password === 'admin@2024') {} $api_secret = getenv('API_SECRET');
define('API_SECRET', 'hardcoded-key'); $db_pass = $_ENV['DB_PASSWORD'];1.2 PHP 弱比较表
| 表达式 | 结果 | 原因 |
|---|---|---|
"0e123" == "0e456" | true | 科学计数法均为 0 |
"0e123" == 0 | true | 字符串转数字 |
"" == 0 | true | 空串转 0 |
"1abc" == 1 | true | 前缀数字 |
"php" == 0 | true (PHP<8) | 非数字串转 0 |
// 危险: == 比较 token — 攻击者提交 0 或 "0e..." 可绕过
if ($_GET['token'] == $stored_token) { grant_access(); }
if (md5($input) == $hash) { authenticate(); } // 0e 开头哈希碰撞
// 安全: hash_equals 防时序攻击 + 严格比较
if (hash_equals($stored_token, $_GET['token'])) { grant_access(); }1.3 JWT 审计
Algorithm Confusion: 服务端 RS256,攻击者改 header 为 HS256,用公钥作 HMAC 密钥签名。
// 危险: 从 token header 读取算法 / 接受 alg:none
$algo = $header->alg; // 攻击者可控
// 安全: 服务端强制指定算法
$decoded = JWT::decode($jwt, new Key($secret, 'RS256'));kid 注入: file_get_contents('/keys/' . $header->kid) 路径遍历;WHERE id='{$header->kid}' SQL 注入。
密钥泄露: 搜索 .env、config/、storage/ 中 JWT 密钥,确认 .gitignore 排除。
1.4 密码重置漏洞
// 危险模式
$token = md5($user->email . time()); // time() 可爆破
$token = substr(md5(rand()), 0, 16); // rand() 种子可预测
$token = base64_encode($user->email); // 无随机性
$user = User::where('reset_token', $token)->first(); // 未绑定用户
// 缺少过期: WHERE created_at > NOW() - INTERVAL 30 MINUTE
// 安全: 不可预测 + 绑定用户 + 过期
$token = bin2hex(random_bytes(32));
DB::insert('reset_tokens', ['user_id'=>$user->id, 'token'=>hash('sha256',$token),
'expires_at'=>date('Y-m-d H:i:s', strtotime('+30 minutes'))]);1.5 OAuth 缺陷
三个检查点: (1) state 参数未校验 → CSRF; (2) redirect_uri 未白名单限制; (3) 仅用 OAuth 返回 email 登录,未检查 email_verified。
---
2. 授权失控
2.1 IDOR 代码模式
// 危险: 直接引用无归属检查
$order = Order::find($_GET['order_id']);
$invoice = file_get_contents("/invoices/" . $_GET['file_id'] . ".pdf");
// 安全: ownership 检查
$order = Order::where('id', $_GET['order_id'])->where('user_id', auth()->id())->firstOrFail();搜索策略: $_GET/$request->input 直接进入 find()/where('id',...) 且缺少当前用户过滤。
2.2 中间件覆盖缺陷
// 路由分组遗漏
Route::middleware(['auth','admin'])->group(function () {
Route::get('/admin/dashboard', [AdminController::class, 'index']);
});
Route::get('/admin/export', [AdminController::class, 'export']); // 遗漏!
// withoutMiddleware 滥用
Route::get('/api/data', [DataController::class, 'index'])->withoutMiddleware('auth');发现方法: php artisan route:list 导出,对比中间件列找漏洞。
2.3 水平越权 vs 垂直越权
水平: Order::find($id) 无 user_id 过滤,同角色跨用户访问。
垂直: 仅前端隐藏按钮,后端 deleteUser($id) 缺少 role !== 'admin' 检查。
---
3. 安全配置
3.1 php.ini 安全基线
| 配置项 | 安全值 | 风险 |
|---|---|---|
display_errors | Off | 泄露路径/SQL/栈 |
log_errors | On | 错误写日志不输出 |
expose_php | Off | 隐藏 X-Powered-By |
allow_url_include | Off | 阻止远程包含 |
allow_url_fopen | Off | 减少 SSRF 面 |
open_basedir | 项目目录 | 限制文件范围 |
disable_functions | exec,system,... | 禁危险函数 |
session.cookie_httponly | 1 | 阻止 JS 读 cookie |
session.cookie_secure | 1 | 仅 HTTPS |
session.cookie_samesite | Strict/Lax | 防 CSRF |
session.use_strict_mode | 1 | 拒绝未初始化 SID |
session.sid_length | >=48 | 增加 SID 熵 |
upload_max_filesize | 合理值 | 防资源耗尽 |
max_input_vars | 1000 | 防 HashDoS |
memory_limit | 合理值 | 防 OOM |
3.2 框架调试模式
grep -rn "APP_DEBUG\s*=\s*true" .env .env.production # Laravel
grep -rn "app_debug\s*=>\s*true" config/ # ThinkPHP
grep -rn "define.*DEBUG.*true" --include="*.php" # 自定义泄露内容: 栈跟踪、环境变量(数据库密码)、SQL 日志、已加载文件列表。
3.3 CORS 策略审计
// 危险: 任意源 + 凭据 / 反射 Origin 无校验
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
// 安全: 白名单
$allowed = ['https://app.example.com'];
if (in_array($_SERVER['HTTP_ORIGIN'], $allowed)) {
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
}3.4 安全 HTTP 头
必须设置: X-Frame-Options: DENY、Content-Security-Policy: default-src 'self'、X-Content-Type-Options: nosniff、Strict-Transport-Security: max-age=31536000、Referrer-Policy: strict-origin-when-cross-origin。搜索 header( 调用或中间件配置确认。
---
4. 密码学误用
4.1 密码哈希
// 危险: 弱哈希
$hash = md5($password); // 彩虹表/GPU 秒破
$hash = md5($password . $salt); // 自定义盐迭代不足
// 安全
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
if (password_verify($input, $stored_hash)) { /* ok */ }审计: 搜索 md5(/sha1(,排除非密码用途,聚焦密码存储和认证比较。
4.2 对称加密
// 危险: ECB 确定性加密 — 相同明文=相同密文
$cipher = openssl_encrypt($data, 'AES-128-ECB', $key);
// 安全: GCM 认证加密
$iv = random_bytes(16);
$cipher = openssl_encrypt($data, 'AES-256-GCM', $key, 0, $iv, $tag);CBC Padding Oracle: 解密失败返回不同错误时可逐字节还原明文。检查错误处理是否统一。
密钥管理: 搜索 openssl_encrypt/mcrypt_encrypt 的 $key/$iv 来源,硬编码 $key='MySecret' 为 Critical。安全做法: getenv('ENCRYPT_KEY') 或密钥管理服务。
4.3 随机数
// 危险: 可预测 // 安全: 密码学安全
$token = md5(mt_rand()); $token = bin2hex(random_bytes(32));
$code = rand(100000, 999999); $code = random_int(100000, 999999);
$id = uniqid('', true); // uniqid 基于时间,不可用于安全场景搜索 mt_rand/rand(/uniqid(/srand(,判断是否用于令牌、验证码、密钥生成。
---
5. 业务逻辑
5.1 竞争条件
// 危险: 先查后减无锁 — 并发可双花
$balance = DB::table('wallets')->where('user_id', $uid)->value('balance');
if ($balance >= $amount) {
DB::table('wallets')->where('user_id', $uid)->update(['balance' => $balance - $amount]);
}
// 安全 1: 悲观锁
DB::transaction(function () use ($uid, $amount) {
$w = DB::table('wallets')->where('user_id', $uid)->lockForUpdate()->first();
if ($w->balance >= $amount) {
DB::table('wallets')->where('user_id', $uid)->update(['balance' => $w->balance - $amount]);
}
});
// 安全 2: 原子 UPDATE
DB::table('wallets')->where('user_id', $uid)->where('balance', '>=', $amount)->decrement('balance', $amount);搜索策略: SELECT + UPDATE 同表无事务,关注余额/库存/积分/优惠券。
5.2 支付流程审计
三检查点: (1) 金额来源 — $_POST['amount'] 客户端可控为 Critical,必须服务端从订单计算; (2) 签名验证 — 支付回调需 verifySignature 防篡改; (3) 幂等性 — 回调重放防重复发货,需检查订单状态。
5.3 状态机跳步
// 危险: 直接设置任意状态
Order::where('id', $id)->update(['status' => $request->status]);
// 安全: 合法转换矩阵
$transitions = ['pending'=>['paid','cancelled'], 'paid'=>['shipped','refunding']];
if (!in_array($next, $transitions[$current] ?? [])) { abort(422); }5.4 批量操作频率限制
审计关注: 短信发送、优惠券发放、积分赠送、邀请注册等高价值操作。检查是否有单次数量上限 (array_slice) 和时间窗口频率限制 (Cache/Redis 计数器)。无限制的批量接口可被滥用造成资金损失。