第一步必须审查依赖安全性:运行composer outdated和composer audit,核对composer.lock中关键包版本并比对osv.dev漏洞库;第二步定位用户输入入口,全局搜索超全局变量及request方法调用;第三步追踪高危函数调用链,检查sql拼接、反序列化等是否过滤用户输入;第四步验证权限控制,确认gate策略、@can指令与中间件协同生效;第五步严查文件上传逻辑,防范目录穿越、扩展名绕过及服务端执行风险。

你要对一个正在上线或即将交付的PHP框架项目做安全审查,不是走形式,而是真要揪出SQL注入、越权访问、文件上传执行这类能直接导致服务器沦陷的问题。
第一步:确认依赖组件是否带毒
打开终端,进入项目根目录,运行 【composer outdated】,看哪些包标着 <fg>security</fg>=red> 或版本明显滞后;
接着执行 【composer audit】(若提示未安装插件,则先运行 composer require --dev roave/security-advisories:dev-master);
重点检查 composer.lock 中 monolog/monolog、guzzlehttp/guzzle、laravel/framework(或对应框架名)的提交哈希值,去 OSV.dev 搜索该哈希,确认是否存在未修复的 CVE-2024-XXXXX 类漏洞;
如果发现 symfony/http-foundation 版本是 5.4.31,而官方已发布 5.4.39 修复了 Content-Disposition 头解析绕过漏洞,就必须立刻升级——这个漏洞能让攻击者伪造文件名绕过白名单校验。
第二步:抓出所有用户输入入口点
方法一:全局搜索敏感超全局变量
在 PhpStorm 中按 Ctrl+Shift+F,勾选「正则表达式」,输入:\$_(GET|POST|REQUEST|COOKIE|SERVER\['HTTP_|FILES),把所有匹配行导出为文本;
方法二:定位入口控制器与中间件
找到 app/Http/Controllers 下所有控制器,逐个打开,扫描 request()->xxx()、$request->input('xxx')、$request->file('xxx') 调用位置;
特别注意那些没加 validate() 或没走 Form Request 类的方法——比如 store() 里直接用 $request->all() 接收全部参数,却只对 email 字段做了 filter_var,其余字段全裸奔。
第三步:顺藤摸瓜查高危函数调用链
① 打开 IDE 的「结构视图」,筛选出所有含 query(、execute(、exec(、system(、include(、require_once( 的函数;
② 对每个结果,右键 → 「Find Usages」,查看调用它的上层函数;
③ 沿着调用栈向上追溯,直到找到第一个接收用户输入的变量;
④ 检查该变量在传入高危函数前是否经过过滤:比如 mysqli_query($conn, "SELECT * FROM user WHERE id = " . $_GET['id']) 中,$_GET['id'] 既没过 intval(),也没进预处理绑定,这就是实打实的 SQL 注入点;
⑤ 遇到 unserialize($data) 且 $data 来自 $_COOKIE 或 $_SESSION,立即标记为反序列化风险——ThinkPHP 5.1.29 就因此被利用构造 Phar 文件触发 RCE。
第四步:验证权限控制是否形同虚设
打开 app/Providers/AuthServiceProvider.php,检查 Gate::define() 是否覆盖了所有敏感操作,例如 'delete-post' 策略是否真的校验了 $user->id === $post->user_id;
搜索所有 @can('xxx') Blade 指令,确认对应路由是否同时在控制器中也做了 $this->authorize('xxx', $model);
手动修改 URL 中的 ID 参数,比如把 /admin/users/123/edit 改成 /admin/users/456/edit,看是否能成功加载他人编辑页——如果能,说明中间件 auth:admin 没拦住,或者策略里漏写了模型绑定校验。
第五步:揪出文件上传路径里的定时炸弹
搜索 move_uploaded_file(、$request->file(、Storage::putFile(,定位所有上传逻辑;
检查目标路径是否动态拼接:如 $path = 'uploads/' . $_GET['type'] . '/' . $file->getClientOriginalName(); ——【这里 $_GET['type'] 完全可控,攻击者可传入 ../public/shell 实现目录穿越】;
确认上传后文件是否被重命名:若仍保留原始扩展名,且未做 MIME 类型+内容头双重校验,就可能绕过 .php 黑名单;
登录服务器,执行 ls -lZ /var/www/html/storage/app/public/uploads/,验证该目录是否被 Nginx/Apache 配置为禁止执行 PHP 脚本——如果 SELinux 上下文显示 httpd_exec_t,立刻修正为 httpd_sys_content_t。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











