阅读Laravel documentation我明白了:
Note: The Laravel query builder uses PDO parameter binding throughout to protect your application against SQL injection attacks. There is no need to clean strings being passed as bindings.
如果我只按以下方式制作查询,那还是适用吗?
DB::query("SELECT * from table WHERE id like " . $id);
答案 0 :(得分:4)
让我们接受这句话并强调关键词:
无需清除作为绑定传递的字符串。
在您的示例中,$id
未作为绑定传递,它只是被注入到原始SQL中,因此它不受保护。
您应该遵循防止SQL注入的标准做法:
intval($id)
DB::getPdo()
/ DB::getReadPdo()
获取基础PDO对象并使用PDO::quote()
来正确转义字符串DB
外观可以运行完全参数化的查询,例如DB::select('SELECT * FROM users WHERE users.id = ?', array($userId));
参数化查询通常被认为是注入预防中的黄金标准,也是Eloquent在您使用查询构建器时在内部使用的内容。我们的想法是,您首先向数据库(或者至少是数据库驱动程序)提供完整的查询而根本没有用户输入,因此毫无疑问应该使用哪些表和列。然后,您将用户输入作为完全独立的数据传递,该数据从未实际写入SQL,只应用于您已发送的查询。
参数化查询不能为您做任何事情 - 例如,大多数库including PDO, can't bind a table or column name as a parameter。这是因为它每次运行时实际上会创建一个不同的查询,从而否定了查询和数据之间的分离。如果你想这样做,你需要一些其他方法来确保安全 - 通常,允许值的白名单是最好的主意。
答案 1 :(得分:1)
不,DB :: query()不是Query Builder概念的一部分。相反,这将受到保护:
DB::table('table')->where('id', 'like', $id)->get();
答案 2 :(得分:0)
但保护查询的最佳方法是使用最大的查询生成器:
DB::table('table')->where('id', 'like', $id)->get();
如果您真的被迫编写原始查询,另一种保护查询的方法是将数据转换为它们应该是的类型:
DB::query(DB::raw("SELECT * from table WHERE id like " . (int) $id));
在这种情况下,如果$id
为'some exploit'
,则查询将为:
SELECT * from table WHERE id like 0
在Query Builder中,您还可以传递这样的参数(绑定)以加强查询的安全性:
DB::select('SELECT * FROM users WHERE users.id = ?', array($userId));