DB::raw直接拼接字符串是高危操作,因其不校验安全性,仅原样插入SQL;动态值必须剥离并用whereRaw等配合bindings绑定,字段名等标识符须白名单校验。

DB::raw 直接拼接字符串就是高危操作
DB::raw 本身不校验 SQL 语法或参数安全性,它只是把传入的字符串原样塞进查询语句。一旦你用字符串拼接方式注入用户输入,比如 DB::raw("CONCAT('Hello ', '" . $request->input('name') . "')"),就等于在裸奔——$request->input('name') 是 'admin' OR 1=1 -- ' 这种 payload 时,立刻触发 SQL 注入。
必须用参数绑定替代字符串拼接
安全做法是把动态值全部交给 Laravel 查询构建器处理,让 ? 占位符走 PDO 参数绑定流程,底层由数据库驱动完成转义与类型隔离。即使值含单引号、反斜杠、二进制数据,也不会破坏 SQL 结构。
- ✅ 正确:用
whereRaw+ 数组绑定,例如->whereRaw('email LIKE ?', ["%{$search}%"]) - ✅ 正确:用
selectRaw配合后续where分离逻辑,例如selectRaw('COUNT(*) as cnt')->where('status', 'active') - ❌ 错误:用
DB::raw包裹含变量的字符串,例如DB::raw("updated_at > '{$date}'") - ⚠️ 危险:用
sprintf或str_replace手动“过滤”后再进DB::raw,这类白名单/替换逻辑极易绕过
哪些场景看似合理实则暗藏风险
开发者常误以为“只拼字段名或固定枚举值”就安全,但只要来源不可控,就存在漏洞可能。比如排序字段来自 URL 查询参数、GROUP BY 的列名由前端选择、JSON_EXTRACT 路径由用户指定——这些都属于用户可控输入,不能直接进 DB::raw。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 排序字段:不要写
orderBy(DB::raw($request->input('sort')), 'desc');应白名单校验后映射,例如$allowed = ['created_at', 'name']; $sort = in_array($sort, $allowed) ? $sort : 'id'; - 动态表名或列名:Laravel 不支持绑定这些,必须严格白名单 + 字符串验证(如仅允许字母数字下划线),且不能依赖
addslashes或正则替换 - JSON 路径表达式:MySQL 的
JSON_EXTRACT(data, '$.user.name')中路径部分若来自请求,需限制为预定义键名,避免注入$[0].`x` OR 1=1类变体
升级 PHP 版本不能绕过这个逻辑缺陷
当前(2026年11月)PHP 8.5.12 已修复 CNVD-2026-41674 等内核级 RCE 漏洞,但这和 DB::raw 使用不当导致的 SQL 注入完全无关。后者是应用层逻辑错误,发生在 Laravel 查询构建阶段,PHP 解释器是否健壮不影响该漏洞触发条件。哪怕你用的是刚发布的 PHP 8.5.12,只要代码里还存在 DB::raw("...{$userInput}..."),SQL 注入风险就真实存在。










