4

Я все еще учась писать хорошие запросы с помощью ActiveRecord. Мне любопытно, будет ли этот запрос подвержен SQL-инъекции из-за того, как я использую поле даты в запросе.Rails - этот запрос открыт для SQL-инъекции?

Может ли кто-нибудь указать любые очевидные ошибки или какие-либо более эффективные способы написать этот запрос?

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

Просто Интонацию , Я нашел несколько случаев, когда выполнение params [: id] .to_i' спасло нас от уязвимостей безопасности в рельсах. Таким образом, даже рельсы заявляют, что избегают параметров в данном методе, не доверяйте никому :) –

+0

Можете ли вы рассказать о том, как «params [: id] .to_i' предотвратили уязвимости системы безопасности? – Catfish

+0

'' 1 ".to_i' возвращает целое число' 1'. '' some_string ".to_i' возвращает' 0' –

ответ

8

Вы должны использовать только предпочтительный способ включения параметров, которые должны быть безопасными. Выезд this guide:

Создание собственных условий как чистых строк может стать уязвимым для эксплойтов SQL-инъекций. Например, Client.where("first_name LIKE '%#{params[:first_name]}%'") небезопасен. См. Следующий раздел для предпочтительного способа обработки условий с использованием массива.

Try:

@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') 
+0

Почему код, который вы дали сразу после 'Try:' безопаснее, чем его? – Zippie

+0

@ Zippie надеюсь, что мой ответ прояснит – mkk

+0

ха-ха, просто посмотрев на него, спасибо! :) – Zippie

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

Смежные вопросы