Rails is this query open to sql injection?

烈酒焚心 提交于 2019-12-05 14:39:23

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')

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'')

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