PHP框架OAuth 2.0审计需重点检查硬编码密钥、state缺失或未销毁、redirect_uri校验绕过、refresh_token重放及auth code非一次性等漏洞,每项均须严格遵循安全规范。

在PHP框架审计中识别OAuth 2.0授权环节的硬编码密钥、state缺失、redirect_uri校验绕过、refresh_token重放等高危漏洞,是保障第三方登录与API授权链路不被劫持的关键动作。
检查客户端凭证是否硬编码或泄露
打开框架的配置文件(如config/oauth.php、.env或app/Providers/AuthServiceProvider.php),搜索client_id、client_secret、secret等关键词。
若发现client_secret明文写死在前端JS、Blade模板、路由闭包或未加密的.env中,【该凭证已可被任意调用方复用,必须立即轮换并移至服务端密钥管理器】。
特别注意Laravel项目中Passport::personalAccessClientId()若被直接echo或JSON输出,等同于暴露长期有效凭证。
立即学习“PHP免费学习笔记(深入)”;
验证state参数生成与销毁逻辑
定位授权跳转发起点(常见于AuthController@redirectToProvider或Socialite::redirect()调用处):
① 检查是否调用bin2hex(random_bytes(16))或Str::random(32)生成state;
② 确认生成后是否存入$_SESSION['oauth2_state']或session(['oauth2_state' => $state]);
③ 在回调入口(如AuthController@handleProviderCallback)中,必须存在if (!isset($_SESSION['oauth2_state']) || $_GET['state'] !== $_SESSION['oauth2_state'])校验;
④ 校验通过后,【必须立刻执行unset($_SESSION['oauth2_state'])或session()->forget('oauth2_state')】——漏掉这一步会导致CSRF防护形同虚设。
审计redirect_uri校验强度
方法一:检查ClientRepository实现类(如App\Repositories\ClientRepository)中getClientEntity或validateRedirectUri方法:
若校验逻辑为strpos($redirectUri, $client->redirect_uri) === 0或使用parse_url后仅比对host,【存在协议/端口/路径截断绕过风险,必须改为全字符串精确匹配】。
方法二:查看框架是否启用白名单机制。Laravel Passport默认要求redirect_uris字段为JSON数组,且校验时遍历匹配;若数据库中该字段为单个字符串或为空,说明配置失效。
方法三:手动构造测试请求,将redirect_uri=https://attacker.com/callback拼入授权URL,观察是否被拒绝——允许即存在开放重定向漏洞。
排查refresh_token单次有效性控制
进入RefreshTokenRepository实现类(如App\Repositories\RefreshTokenRepository),检查getNewRefreshToken和revokeRefreshToken方法:
若revokeRefreshToken仅标记is_revoked = 1但未在persistNewRefreshToken中校验旧token状态,攻击者可截获并重复使用同一refresh_token换取多个access_token。
正确逻辑必须满足:每次成功刷新后,【立即调用revokeRefreshToken($oldToken)且数据库行级更新生效】,不可依赖应用层缓存延迟清理。
确认授权码(code)时效与一次性约束
定位AuthCodeRepository实现类,重点审查getNewToken返回值结构:
必须包含expiresIn字段(标准值为600秒),且数据库表中对应字段为DATETIME类型而非INT时间戳;
必须在createAuthCode中调用bin2hex(random_bytes(32))生成code,严禁使用md5(microtime())等可预测方式;
必须在exchangeAccessToken流程末尾调用revokeAuthCode($code)——未执行则授权码可无限次兑换令牌。



















