4

我仍在学习如何使用 ActiveRecord 编写好的查询。我很好奇这个查询是否会因为我在查询中使用日期字段的方式而受到 sql 注入。

有人可以指出任何明显的错误或编写此查询的更好方法吗?

@arrangements_for_month =
  Arrangement.joins(:timeslot).
              where("timeslots.timeslot BETWEEN '#{month}' AND '#{month.end_of_month}'", params[:id]).
              order('location_id')
4

2 回答 2

8

为了安全起见,您应该只使用包含参数的首选方式。查看本指南

将您自己的条件构建为纯字符串可能会使您容易受到 SQL 注入攻击。例如,Client.where("first_name LIKE '%#{params[:first_name]}%'")不安全。有关使用数组处理条件的首选方法,请参阅下一节。

尝试:

@arrangements_for_month = Arrangement.joins(:timeslot)
  .where("timeslots.timeslot BETWEEN ? AND ?", month, month.end_of_month)
  .order('location_id')

只是提醒一下,如果您愿意,还有另一种方法可以使用 ruby​​ 范围来定义范围条件,如链接指南的该部分所述:

Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight)

因此,在不了解您的代码的任何其他信息的情况下,您可能可以执行以下操作:

@arrangements_for_month = Arrangement.joins(:timeslot)
  .where("timeslots.timeslot" => month .. month.end_of_month)
  .order('location_id')
于 2013-03-14T01:19:15.137 回答
6

是的。每次将用户的输入插入查询字符串时,它都是易受攻击的。如果month将是:

5' AND '8'; DROP TABLE timeslots;--

你可能会遇到严重的麻烦。更不用说删除数据库等。

我没有完全复制这个查询,但是由于使用了acts_as_paranoid插件,在我的查询中类似的[我必须添加]:

SomeModel.pluck(:id)
 => [1, 2, 4, 3, 5, 6]

abc = 'a\');delete from some_models where id=6;--'
User.where("name = '#{abc}'")
 => []

SomeModel.pluck(:id)
 => [1, 2, 4, 3, 5] # please note that record with id 6 was deleted!

攻击可能的原因是我可以提供'--(开始评论)。当你使用建议的方式时,即使用 .where("name = ?", "my_name"),那么攻击就不可能了。看一下这个:

abc = 'a\');delete from some_models where id=5;--'

User.where("name = ?", abc)
 => []

SomeModel.pluck(:id)
 => [1, 2, 4, 3, 5] # this time record with id 5 was not deleted

这是第一个查询:

 User Load (1.5ms)  SELECT "users".* FROM "users" WHERE ("users"."deleted_at" IS NULL) AND (name = 'a');delete from some_models where id=6;--')

这是第二个

  User Load (1.0ms)  SELECT "users".* FROM "users" WHERE ("users"."deleted_at" IS NULL) AND (name = 'a'');delete from some_models where id=5;--')

请注意'第二个中的附加内容-query(name = 'a'')

于 2013-03-14T01:24:49.453 回答