我还在学习如何使用ActiveRecord编写好的查询。我很好奇这个查询是否受到sql注入的影响,因为我在查询中使用了日期字段。
有人可以指出任何明显的错误或更好的方法来撰写此查询吗?
@arrangements_for_month =
Arrangement.joins(:timeslot).
where("timeslots.timeslot BETWEEN '#{month}' AND '#{month.end_of_month}'", params[:id]).
order('location_id')
答案 0 :(得分:8)
您应该使用包含参数的首选方法来保证安全。查看this guide:
将自己的条件构建为纯字符串可能会使您容易受到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')
如果你愿意的话,只需要提醒一下,有另一种方法来定义范围条件,例如使用红宝石范围,如链接指南的那一节所述:
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')
答案 1 :(得分: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'')