CVE-2024-29291是Laravel 8–11版本因APP_DEBUG=true触发的调试模式信息泄露漏洞,会导致.env、数据库凭证等敏感信息在错误页面明文暴露;软删除本身不是漏洞,其数据泄露源于业务权限控制缺失或接口设计不当。

Laravel 8.x 本身没有官方定义的“软删除数据泄露漏洞”。你提到的这个说法,大概率是混淆了两个独立但常被同时讨论的安全问题:
✅ CVE-2024-29291:这是真实存在的 Laravel 调试模式信息泄露漏洞(影响 Laravel 8–11),它与软删除无关,而是因
APP_DEBUG=true+ 特定异常触发,导致.env、数据库密码等敏感信息在错误页面中明文暴露。-
❌ 软删除不是漏洞,而是一种功能机制:
deleted_at字段的存在、withTrashed()的可用性、restore()的行为——这些都属于设计使然,不是安全缺陷。所谓“数据泄露”,通常指:- 开发者未限制权限,让普通用户能调用
withTrashed()->get()查到已删数据; - API 接口未过滤软删除状态,直接返回
User::all()而非User::whereNull('deleted_at')->get(); - 管理后台开放了
/users?with_trashed=1且无鉴权/审计。
- 开发者未限制权限,让普通用户能调用
所以,真正要“修复”的不是 Laravel 软删除本身,而是你的业务逻辑和访问控制是否合理。以下是关键落地方案:
明确软删除数据的可见边界
软删除记录默认不会出现在任何常规查询中(如 User::all()、User::find(1))。只有显式调用 withTrashed() 或 onlyTrashed() 才能查到它们。
✅ 正确做法:
- 所有面向用户的列表、详情接口,坚持使用默认查询(不加
withTrashed()); - 管理后台如需查看已删数据,必须满足两个条件:
- 用户拥有
viewTrashedUsers等细粒度权限(通过 Gate 或 Policy 控制); - 接口路径或参数明确标识操作意图(如
GET /admin/users/trashed),而非模糊的?include_deleted=1。
- 用户拥有
防止 restore() 被未授权调用
restore() 是写操作,必须校验身份与权限:
- 在 Controller 中强制使用 Policy:
$this->authorize('restore', $user); $user->restore(); - 对应的
UserPolicy@restore()中判断:public function restore(User $user, User $model): bool { return $user->hasRole('admin') && $model->trashed(); }
避免调试模式导致的间接泄露(CVE-2024-29291)
这才是 Laravel 8.x 真正需要“修复”的安全项:
- ✅ 生产环境必须设置
.env中APP_DEBUG=false(这是硬性红线); - ✅ 运行
php artisan config:clear确保配置生效; - ✅ 检查 Nginx/Apache 是否禁止访问
.env、storage/logs/等敏感路径; - ✅ 升级到 Laravel 8.83.24+、9.52.16+、10.48.14+ 或 11.x(这些版本已修复 CVE-2024-29291);
- ✅ 若无法立即升级,可临时在
App\Exceptions\Handler.php中重写render()方法,对调试模式下的异常响应做内容脱敏(如清空$exception->getTraceAsString()或替换敏感变量值)。
补充:防止软删除被绕过的技术误用
- 不要用
DB::table('users')->get()替代 Eloquent 查询——它完全绕过SoftDeletestrait 和deleted_at过滤; - 不要在
whereRaw()或原生 SQL 中遗漏AND deleted_at IS NULL条件; - 前端传参如
status=deleted不能直接映射为onlyTrashed(),必须经后端权限+上下文双重校验。
软删除本身很安全,危险的是裸露的接口、宽松的权限、开着的调试模式。把这三块堵住,就不存在所谓“软删除数据泄露漏洞”。


















