Laravel查询构建器防注入吗

wen PHP项目 2

本文目录导读:

Laravel查询构建器防注入吗

  1. 安全示例
  2. 不安全的情况(需要避免)
  3. 查看实际执行的 SQL

是的,Laravel 的查询构建器(Query Builder)是防 SQL 注入的

Laravel 查询构建器通过 PDO 参数绑定(Parameter Binding) 机制来防止 SQL 注入,这意味着:

  1. 查询构建器:当你使用 whereinsertupdate 等方法时,传入的值不会被直接拼接到 SQL 语句中,而是作为参数进行绑定,由数据库驱动处理转义。
  2. 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 推荐的方式使用查询构建器,不刻意绕过参数绑定机制,你的应用就是安全的。

抱歉,评论功能暂时关闭!