我是否需要在laravel中清除DB :: query调用的用户输入?

时间:2014-04-03 22:59:29

标签: php security laravel

阅读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);

3 个答案:

答案 0 :(得分:4)

让我们接受这句话并强调关键词:

  

无需清除作为绑定传递的字符串

在您的示例中,$id未作为绑定传递,它只是被注入到原始SQL中,因此它不受保护

您应该遵循防止SQL注入的标准做法:

  • 在这种情况下,输入始终是整数,您可以使用intval($id)
  • 您可以使用DB::getPdo() / DB::getReadPdo()获取基础PDO对象并使用PDO::quote()来正确转义字符串
  • 虽然文档相当差,但Laravel的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));