本文目录导读:

是的,Laravel 的查询构建器(Query Builder)是防 SQL 注入的。
Laravel 查询构建器通过 PDO 参数绑定(Parameter Binding) 机制来防止 SQL 注入,这意味着:
- 查询构建器:当你使用
where、insert、update等方法时,传入的值不会被直接拼接到 SQL 语句中,而是作为参数进行绑定,由数据库驱动处理转义。 - Eloquent ORM:继承自查询构建器,同样安全。
安全示例
// ✅ 安全:值通过参数绑定传递
$users = DB::table('users')
->where('email', $request->input('email'))
->get();
// ✅ 安全:多个条件
DB::table('users')->insert([
'name' => $request->name, // 绑定为参数
'email' => $request->email // 绑定为参数
]);
不安全的情况(需要避免)
使用 DB::raw() 直接拼接用户输入
// ❌ 危险!用户输入直接拼接到 SQL
$users = DB::select("SELECT * FROM users WHERE id = " . $request->id);
// ✅ 应该使用参数绑定
$users = DB::select("SELECT * FROM users WHERE id = ?", [$request->id]);
在 whereRaw() 或 orderByRaw() 中直接拼接
// ❌ 危险
$users = DB::table('users')
->whereRaw("name = '" . $request->name . "'")
->get();
// ✅ 安全:使用问号占位符
$users = DB::table('users')
->whereRaw("name = ?", [$request->name])
->get();
表名和列名参数绑定
注意:参数绑定只保护值,不保护表名和列名,如果你直接拼接表名或列名,同样存在风险:
// ❌ 危险:表名直接拼接
$table = "users_" . $request->user_type;
DB::table($table)->get();
// ✅ 安全做法:白名单验证
$allowedTables = ['users_admin', 'users_regular'];
$table = in_array($request->user_type, $allowedTables)
? "users_" . $request->user_type
: "users_regular";
DB::table($table)->get();
查看实际执行的 SQL
可以开启查询日志来查看参数绑定的实际效果:
DB::enableQueryLog();
DB::table('users')
->where('email', 'test@example.com')
->get();
dd(DB::getQueryLog());
// 输出类似:["query" => "select * from `users` where `email` = ?", "bindings" => ["test@example.com"]]
- ✅ 正常使用查询构建器:
where()、insert()、update()、delete()等方法 → 安全 - ✅ 使用占位符的
whereRaw():whereRaw("name = ?", [$value])→ 安全 - ❌
DB::raw()或DB::select()直接拼接 → 危险 - ❌
whereRaw()中直接拼接字符串 → 危险 - ❌ 用户输入作为表名或列名 → 危险(需白名单过滤)
只要按照 Laravel 推荐的方式使用查询构建器,不刻意绕过参数绑定机制,你的应用就是安全的。