hyperf特有安全风险需聚焦协程机制、注解扫描链、中间件生命周期及swoole交互:检查php --ri swoole中support coroutines是否enabled;确认swoole.use_shortname=0;关闭expose_php;验证签名中间件时间戳校验与上下文隔离;审计注解路由是否被全局中间件拦截。

在PHP框架安全审计中识别Hyperf特有的风险点,需聚焦其协程机制、注解扫描链、中间件生命周期及Swoole底层交互带来的独特攻击面,不能套用Laravel或ThinkPHP的常规审计路径。
确认Hyperf运行环境是否启用协程安全基线
执行 php --ri swoole,检查输出中 support coroutines: enabled 是否存在;若为 disabled 或未显示该行,说明 Swoole 扩展未启用协程模式,Hyperf 实际以伪协程方式运行,此时中间件成员变量污染、上下文隔离失效等典型协程安全问题将不复存在,但会引入同步阻塞导致的DoS风险。
打开 php.ini,确认 swoole.use_shortname=0 已设置;若为 on,Hyperf 的部分内置类(如 Co\Socket)可能被短名覆盖,造成依赖注入容器解析失败,进而绕过中间件校验逻辑。
运行 php bin/hyperf.php start 后立即访问 /favicon.ico,观察响应头是否含 Server: Hyperf 且无 PHP 版本泄露;若返回 X-Powered-By: PHP/8.1.23,说明 expose_php=On 未关闭,攻击者可据此选择对应版本的反序列化链。
抓取并逆向分析签名验签中间件逻辑
方法一:从请求 Header 中定位签名字段
使用 Burp Suite 拦截任意业务接口请求,查找是否存在 sign、X-Signature、Authorization: Sign 等自定义签名头;若存在,记录下配套的 time-stamp 和 nonce-str 字段值。
方法二:定位后端验签中间件类文件
在项目根目录执行 grep -r "time-stamp\|nonce-str\|sign" app/Middleware/ --include="*.php";若无结果,扩大搜索至 app/ 全局,重点关注命名含 Verify、Auth、Signature 的类;找到后,确认其是否实现 MiddlewareInterface 并在 process() 中调用 $request->getHeaderLine() 提取签名参数。
方法三:验证签名算法是否可被降级绕过
构造两个相同参数的请求,仅修改 time-stamp 值为当前时间±30秒以外(如 ±61 秒),观察响应是否返回 401 Signature expired;若返回 200 或 500,说明时间戳校验逻辑缺失或未生效,重放攻击可直接利用。
检测中间件中是否存在协程上下文污染
第一步:静态扫描高危成员变量声明
在 app/Middleware/ 目录下执行 grep -n "protected \$\|private \$" *.php | grep -E "(user|token|data|info|context)";若输出中出现类似 protected $currentUser = []; 的语句,且该中间件未配置为每次请求新建实例(即未在 config/autoload/middlewares.php 中设 'singleton' => false),则存在跨协程数据污染风险。
第二步:动态验证 Context::set 是否被正确使用
在疑似中间件的 process() 方法内搜索 Context::set 调用;若未找到,或只在 if 分支内调用而主流程直接赋值给 $this->xxx,说明开发者误将协程局部状态存入单例对象属性——此时并发请求中用户A的 token 可能被用户B读取。
第三步:检查请求属性传递链是否断裂
若中间件使用 $request->withAttribute('auth_user', $user) 注入数据,需跟进控制器中是否通过 $request->getAttribute('auth_user') 获取;若控制器改用 $this->authUser 成员变量访问,且该变量在构造函数中被赋值,则整个认证上下文已脱离协程隔离范围,必须重构。
审计注解路由是否暴露未授权入口
运行 php bin/hyperf.php gen:controller TestController --method index 创建测试控制器,然后执行 php bin/hyperf.php route:list;观察输出中是否列出 GET /test/index 路由;若未出现,说明注解扫描未生效,需检查 config/autoload/annotations.php 中 'paths' 是否包含 app/Controller,且 'cacheable' 是否为 false(开发环境必须关闭缓存,否则新增注解不生效)。
手动在 app/Controller 下创建一个无任何权限控制注解的控制器,例如 DebugController.php,内容含 #[GetMapping("/debug/env")] public function env() { return $_ENV; };访问该路径,若返回完整环境变量(含数据库密码、密钥),证明注解路由未被中间件全局拦截,且开发者未启用生产环境配置覆盖。
检查 config/autoload/middlewares.php 中全局中间件数组,确认 'http' => [ ... ] 是否包含鉴权类(如 App\Middleware\AuthMiddleware::class);若为空或仅含日志类,所有注解路由均处于裸奔状态,无需登录即可调用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











