Laravel作为目前PHP生态中最主流的开发框架之一,自带了很多安全机制,比如ORM参数绑定、CSRF中间件、bcrypt加密等。但框架安全不等于项目安全,很多开发者在实际开发中为了图方便,绕过了这些机制,或者配置不当,导致网站依然存在可被利用的漏洞。这篇文章就来系统讲一讲Laravel网站常见漏洞的测试方法和对应的修复方案。

一、Laravel网站常见漏洞类型有哪些
在动手测试之前,先要清楚Laravel项目中容易出问题的几个地方。第一个是SQL注入,虽然Eloquent和Query Builder默认使用参数绑定,但不少开发者会直接拼接原始SQL,比如DB::raw配合变量拼接,这就是典型的注入点。第二个是CSRF跨站请求伪造,有些项目为了接口方便直接在VerifyCsrfToken中排除了大段路由,等于把防护关掉了。
第三个是文件上传漏洞,Laravel的存储层只负责保存文件,如果上传时没有校验文件类型和后缀,攻击者就可以上传PHP木马文件拿到服务器权限。第四个是批量赋值漏洞,Model的$fillable如果不加限制,或者滥用$guarded为空数组,攻击者可以通过构造请求参数篡改is_admin这类敏感字段。
除此之外,还有一些容易被忽视的问题:APP_KEY泄露导致session可被伪造、.env文件可被直接访问、调试模式在生产环境开启导致报错信息暴露数据库结构、日志中记录了用户明文密码等。这些问题单个看起来不严重,组合起来往往就是一次完整入侵的突破口。
二、如何测试Laravel网站是否存在漏洞
1. 手工测试常见漏洞
手工测试是最直接的方式。测试SQL注入时,可以在所有接受用户输入的参数后面加单引号、双引号或者and 1=1这类payload,观察返回的报错信息或者页面差异。如果项目开启了debug模式,报错页会直接暴露SQL语句,说明注入点大概率存在。测试CSRF时,可以构造一个本地HTML表单,指向目标站点的写操作接口,如果请求成功执行,说明CSRF防护被绕过或者被关闭了。
测试文件上传时,可以尝试上传一个改了后缀的脚本文件,比如把webshell.php改成webshell.php.jpg,或者利用双扩展名和大小写绕过。测试越权时,注册两个普通账号,用A账号的登录态去访问B账号的资源URL,比如修改订单、查看个人信息的接口,如果数据能正常返回,说明存在水平越权。
2. 借助自动化工具扫描
除了手工测试,也可以使用自动化工具提高效率。常见的组合有Burp Suite抓包分析、SQLMap检测注入点、Nikto和OWASP ZAP做整体扫描。SQLMap使用时把目标URL和参数传进去,例如sqlmap -u "http://target.com/search?q=test" --batch,注意只对自己有授权的站点测试,未经授权的渗透测试是违法行为。
另外建议开启并定期检查Laravel的日志文件,位于storage\logs\laravel.log。很多攻击尝试会在日志里留下痕迹,比如大量404、异常的ValidationException报错等,这些都是排查线索。
三、各类漏洞的具体修复方案
1. SQL注入修复
修复原则很简单:所有涉及用户输入的查询都必须使用参数绑定。用Eloquent或Query Builder时天然支持,比如User::where('email', $request->email)->first()是安全的。如果必须写原生SQL,一定要用问号占位符:DB::select('select * from users where status = ?', [$status]),严禁把变量直接拼进SQL字符串里。对于DB::raw的使用要格外小心,raw内部不能再拼接外部输入,如果确实需要,可以用whereRaw配合绑定参数数组。
2. CSRF防护配置
确保web中间件组中包含VerifyCsrfToken,不要因为嫌麻烦就在$except数组里加入大量路由。确实需要免CSRF的接口,比如支付回调,应该单独列出并且用签名校验代替。表单中记得加上@csrf指令,前端AJAX请求则要在headers中携带X-CSRF-TOKEN,可以通过在页面meta标签中输出csrf_token来实现。
3. 文件上传加固
上传校验建议使用Laravel的Validation规则,白名单限制后缀和MIME类型:$request->validate(['file' => 'mimes:jpg,jpeg,png,pdf|max:5120'])。同时要重命名文件,不要使用用户上传时的原始文件名,可以用md5或uuid生成新文件名。上传目录不要放在web可访问的public目录下,或者至少禁止该目录执行PHP,在Nginx中对该location禁用脚本解析即可。
4. 批量赋值与越权修复
每个Model都要明确声明$fillable白名单,永远不要使用空的$guarded。控制器中创建和更新数据时,用$request->validated()或only方法取出明确允许的字段,而不是直接把$request->all()塞进create方法。越权问题的修复要点是每个数据操作都校验归属:$order = Order::where('user_id', auth()->id())->findOrFail($id),而不是先查出来再判断。
四、上线前安全加固清单
最后整理一份实用的加固清单,建议在每次发版前过一遍:
- 确认.env中APP_ENV=production,APP_DEBUG=false,关闭调试模式。
- 检查APP_KEY是否足够随机,如果曾经泄露过必须重新生成并清理旧session。
- 在Nginx或Apache中配置拒绝访问.env、storage、vendor目录,防止敏感文件被下载。
- 及时执行composer update更新框架和依赖,关注Laravel官方的安全公告,历史上多个版本存在过RCE级别的漏洞。
- 登录、找回密码等敏感接口增加限流,Laravel内置的throttle中间件可以直接用。
- 密码必须使用bcrypt或argon2存储,Laravel默认的Hash门面已经处理好,不要自己写md5加盐。
- 清理日志写入内容,禁止把用户密码、token等敏感数据写入日志。
安全不是一次性工作,而是一个持续的过程。建议每季度做一轮完整的漏洞复测,同时关注依赖包的安全更新。把上面这些措施落实到开发规范中,团队成员写代码时形成习惯,Laravel项目的整体安全水平就能得到明显提升。
Laravel漏洞测试Laravel安全修复Laravel网站安全修改时间:2026-09-06 16:00:39