Cat*_*ish 4 ruby activerecord sql-injection ruby-on-rails ruby-on-rails-3
我还在学习如何使用ActiveRecord编写好的查询.我很好奇这个查询是否受sql注入,因为我在查询中使用日期字段的方式.
有人可以指出任何明显的错误或更好的方法来编写这个查询?
@arrangements_for_month =
Arrangement.joins(:timeslot).
where("timeslots.timeslot BETWEEN '#{month}' AND '#{month.end_of_month}'", params[:id]).
order('location_id')
Run Code Online (Sandbox Code Playgroud)
您应该使用包含参数的首选方法来保证安全.看看这个指南:
将自己的条件构建为纯字符串可能会使您容易受到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')
Run Code Online (Sandbox Code Playgroud)
如果你愿意的话,还有另一种方法可以定义范围条件,例如使用ruby范围,如链接指南的那一节所述:
Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight)
Run Code Online (Sandbox Code Playgroud)
因此,在不了解您的代码的任何其他内容的情况下,您可以执行以下操作:
@arrangements_for_month = Arrangement.joins(:timeslot)
.where("timeslots.timeslot" => month .. month.end_of_month)
.order('location_id')
Run Code Online (Sandbox Code Playgroud)
是的.每次将用户的输入插入查询字符串时,它都容易受到攻击.如果month是:
5' AND '8'; DROP TABLE timeslots;--
Run Code Online (Sandbox Code Playgroud)
你可能会遇到严重的麻烦.更不用说丢弃数据库等了.
我没有完全复制这个查询,但由于使用了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!
Run Code Online (Sandbox Code Playgroud)
攻击可能的原因是我可以提供'和--(开始发表评论).当你使用建议的方式,即使用.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
Run Code Online (Sandbox Code Playgroud)
这是第一个查询:
User Load (1.5ms) SELECT "users".* FROM "users" WHERE ("users"."deleted_at" IS NULL) AND (name = 'a');delete from some_models where id=6;--')
Run Code Online (Sandbox Code Playgroud)
这是第二个
User Load (1.0ms) SELECT "users".* FROM "users" WHERE ("users"."deleted_at" IS NULL) AND (name = 'a'');delete from some_models where id=5;--')
Run Code Online (Sandbox Code Playgroud)
请注意'第二个附加内容-query(name = 'a'')