Предупреждение об устаревании метода опасных запросов на Rails 5.2.3 - PullRequest
2 голосов
/ 22 июня 2019

Я нахожусь в процессе обновления моего приложения Rails до 5.2.3

Я использую следующий код в моем приложении.

MyModel.order('LOWER(name) ASC')

Появляется следующее предупреждение об устаревании:

DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "LOWER(name)". Non-attribute arguments will be disallowed in Rails 6.0. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql()

Я изменил вышеупомянутое, рекомендованное предупреждение об устаревании, и предупреждение исчезло:

MyModel.order(Arel.sql('LOWER(name) ASC'))

Я занимался серфингом по поводу связанного обсуждения здесь . Кажется, это изменение введено, чтобы запретить SQL-инъекции.

Но предложение порядка LOWER(name) ASC не содержит ввода пользователя. Почему этот порядок считается небезопасным? Это предполагаемое поведение или я что-то здесь упускаю?

1 Ответ

3 голосов
/ 23 июня 2019

Это предполагаемое поведение, вы связаны с правильным обсуждением, и это именно то, что есть.Я могу переработать это немного больше, хотя это так легко понять.

Во-первых, повторное объяснение инъекции sql, просто для справки:

MyModel.order('LOWER(name) ASC')

Означает, что люди могут передавать любую произвольную строку в функцию заказа, эта строка может содержать имена столбцов и / или тип заказа, введенный пользователем.

Теперь допустим, в вашем веб-приложении есть раскрывающийся список, где пользователь выбирает столбеци еще один, где пользователь выбирает desc или asc и отправляет его.данные.

На действии контроллера можно выполнить следующее:

order_sql = "#{params[:column_name]} #{params[:column_order]}"

Именно здесь может произойти внедрение sql, злонамеренный пользователь может отредактировать данные отправки формы и вместо этогоотправив asc или desc в параметре column_order, он может отправить некоторый сценарий sql, например: asc; delete from table_name_user_guessed_or_knows, вызывающий SQL-инъекции, поэтому рельсы хотят, чтобы пользователи были осторожны при использовании sql в функциях заказа.И разрешить конкретно безопасный sql с пользователем Arel.

Теперь вторая часть, почему name asc разрешено в качестве ввода, а LOWER(name) asc нет?

Предупреждение об устаревании гласит:

ПРЕДУПРЕЖДЕНИЕ О УСТАРЕВАНИИ: опасный метод запроса (метод, аргументы которого используются в качестве необработанного SQL), вызываемый с аргумент (ы) без атрибута : "LOWER (имя) asc ".Аргументы без атрибутов будут запрещены в Rails 6.0.Этот метод не должен вызываться с предоставленными пользователем значениями, такими как параметры запроса или атрибуты модели.Известные безопасные значения можно передать, обернув их в Arel.sql ()

Сосредоточиться на словах: non-attribute argument(s), аргументы без атрибутов - это все, что не является атрибутом,будь то дополнительный SQL, добавляемый в конце для SQL-инъекции, или вызов какого-либо метода для атрибута, потому что вызовы методов также могут использоваться для изменения предполагаемого поведения SQL.

Далее вы спросили:

предложение order LOWER (имя) ASC не содержит ввода пользователя

Rails просто не может узнать, как образовалась строка, он знает только, что это строкапроходитьВот почему он жалуется и хочет, чтобы разработчики были осторожны.

Вот почему name asc разрешен, потому что это простой аргумент атрибута.В то время как LOWER(name) asc выдает предупреждение, потому что это не простой аргумент атрибута, существует аргумент метода для этого аргумента, который потенциально может использоваться для внедрения SQL.
(Очевидно, что злоумышленник, вероятно, не будет использовать простую функцию LOWER для атак, носкорее он будет использовать некоторые специальные функции, может быть, те, которые он определил с помощью подобного подхода инъекции в некоторых предыдущих или даже того же самого вызова).

...