第一步需运行php --ri swoole检查coroutine => enabled和shared memory => enabled;第二步确认入口是否调用swoole\server::start();第三步搜索go()、co::sleep()等协程api以判断是否进入协程上下文。

PHP框架审计中遇到Swoole扩展时,必须单独分析其异步模型、协程上下文、内存驻留特性带来的安全风险,不能套用传统Web请求生命周期的审计逻辑。
确认Swoole是否启用协程及常驻内存模型
第一步:运行 php --ri swoole,检查输出中是否存在 【Coroutine => enabled】 和 【shared memory => enabled】 字样。若缺失任一,说明协程隔离或共享内存机制未激活,后续对全局变量、静态属性、连接池的越权访问审计可跳过。
第二步:查看项目入口文件(如 server.php)是否调用 Swoole\Server::start() 或 Swoole\Http\Server::start()。未调用则为短生命周期脚本,不适用Swoole专项审计流程。
第三步:搜索代码中是否存在 go(function () { ... })、Co::sleep() 或 Swoole\Coroutine\run()。出现即表明业务已进入协程上下文,需重点审查变量作用域与错误处理边界。
审计协程间数据污染风险
方法一:检查全局变量和静态属性是否被多协程并发写入
定位所有 global $xxx、static $xxx、self::$xxx 声明位置,特别关注在 go() 内部或回调函数中修改这些变量的代码。协程共享同一进程内存空间,但不共享协程栈,直接读写全局/静态变量会导致不可预测的数据覆盖——例如用户A的token被用户B的请求意外覆写。
方法二:验证单例对象是否在协程内被重复初始化
搜索 new SingletonClass() 或 SingletonClass::getInstance() 调用点,确认其构造/获取逻辑是否在 go() 块内执行。若单例未做协程ID绑定(如未使用 Swoole\Coroutine::getuid() 作键隔离),则多个协程会共用同一实例,造成状态串扰。
【关键陷阱】 不要依赖 __destruct 清理协程级资源——协程结束时该方法不触发,必须显式调用 unset() 或使用 defer 注册清理函数。
排查HTTP响应头与Cookie注入漏洞
第一步:检索所有 $response->header() 和 $response->cookie() 调用
第二步:检查传入的 $key 和 $value 是否直接拼接用户输入(如 $_GET['redirect']、$_POST['theme'])。Swoole的 header() 不自动过滤换行符,攻击者注入 %0d%0a 可触发HTTP响应头分裂(CRLF Injection)。
第三步:确认 cookie() 的 $httponly 和 $secure 参数是否强制设为 true。未设置将导致敏感Cookie被JavaScript读取或明文传输。
验证文件上传路径与执行权限控制
① 定位所有 $request->files 访问点,确认是否调用 Swoole\HTTP\Request::files 获取上传数据。
② 检查上传后保存路径是否硬编码为 /tmp/、./upload/ 等可写目录,且未校验文件扩展名与MIME类型。Swoole无内置文件类型检测,仅靠前端或 $_FILES['type'] 判断极不可靠。
③ 验证上传目录是否禁用PHP解析:登录服务器执行 ls -ld /path/to/upload,确认目录权限不含 x 位,且Web服务器配置中对该路径明确设置 deny all; 或 SetHandler None。
④ 查看是否调用 $response->sendfile() 直接返回用户上传文件。若路径可控(如 $response->sendfile($_GET['f'])),将导致任意文件读取。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











