Это предполагаемое поведение, вы связаны с правильным обсуждением, и это именно то, что есть.Я могу переработать это немного больше, хотя это так легко понять.
Во-первых, повторное объяснение инъекции 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
для атак, носкорее он будет использовать некоторые специальные функции, может быть, те, которые он определил с помощью подобного подхода инъекции в некоторых предыдущих или даже того же самого вызова).