Rails是这个查询开放sql注入?

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)

Jor*_*eña 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')
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)


mkk*_*mkk 6

是的.每次将用户的输入插入查询字符串时,它都容易受到攻击.如果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'')