Rails is this query open to sql injection?

青春壹個敷衍的年華 提交于 2020-01-13 13:11:18

问题


I'm still learning how to write good queries using ActiveRecord. I'm curious if this query is subject to sql injection because of the way i'm using the date field in the query.

Can someone please point out any obvious mistakes or any better ways to write this query?

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

回答1:


You should just use the preferred way of including parameters to be safe. Check out this guide:

Building your own conditions as pure strings can leave you vulnerable to SQL injection exploits. For example, Client.where("first_name LIKE '%#{params[:first_name]}%'") is not safe. See the next section for the preferred way to handle conditions using an array.

Try:

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

And just a heads up, if you like, there is an alternative way to define a range condition like that using ruby ranges, as described in that section of the linked guide:

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

So, without knowing anything else about your code, you can probably do something like this:

@arrangements_for_month = Arrangement.joins(:timeslot)
  .where("timeslots.timeslot" => month .. month.end_of_month)
  .order('location_id')



回答2:


yes it is. Everytime you insert user's input into the query string, it is vulnerable. If month will be :

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

you might be in serious troubles. Not to mention drop database etc.

I haven't reproduced exactly this query, but something similar [ I had to add ) in my query due to using acts_as_paranoid plugin ]:

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!

The reason why the attack was possible, is that I could provide ' and -- ( which starts comment ). When yo use the suggested way, i.e. using .where("name = ?", "my_name"), then the attack would not be possible. Check this out:

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

This is first query:

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

This is the second

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

Note the additional ' in the second - query(name = 'a'')



来源:https://stackoverflow.com/questions/15399467/rails-is-this-query-open-to-sql-injection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!