ruby-on-rails - Rails 5.2.3 上的危险查询方法弃用警告

标签 ruby-on-rails sql-injection ruby-on-rails-5.2

我正在将我的 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'))

我浏览过相关讨论here .似乎引入了此更改以禁止 SQL 注入(inject)。

但是订单条款LOWER(name) ASC不包含任何用户输入。为什么这种排序被认为是不安全的?这是预期的行为还是我在这里遗漏了什么?

最佳答案

这是预期的行为,你链接到正确的讨论,这正是它的本质。不过,我可以再详细说明一下,这样很容易理解。

首先,重新解释一下sql注入(inject),仅供引用,这样做:

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

意味着人们可以在 order 函数中传递任意字符串,该字符串可能包含来自用户的列名和/或订单类型输入。

现在让我们说,您的网络应用程序中有一个下拉列表,用户选择列,另一个用户选择 desc 或 asc 并提交。数据。

在 Controller Action 上,一个人可能正在做的是:
order_sql = "#{params[:column_name]} #{params[:column_order]}"

这正是 sql 注入(inject)可能发生的地方,恶意用户可以编辑表单提交数据,而不是发送 ascdesccolumn_order参数,他可以发送一些类似的 sql 脚本:asc; delete from table_name_user_guessed_or_knows导致 SQL 注入(inject),这就是为什么 rails 希望用户在 order 函数中使用 sql 时要小心。并专门允许 Arel 用户的安全 sql .

现在是第二部分,为什么 name asc允许作为输入和 LOWER(name) asc不是?

弃用警告内容如下:

DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "LOWER(name) asc". 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()



重点关注: non-attribute argument(s) ,非属性参数是任何不是属性的东西,无论是在末尾附加的用于 SQL 注入(inject)的任何额外 sql,还是对属性的某些方法调用,因为方法调用也可用于改变 SQL 的预期行为。

接下来,你问:

the order clause LOWER(name) ASC doesn't contains any user input



Rails 根本无法知道字符串是如何形成的,它只知道这是一个正在传递的字符串。这就是它提示并希望开发人员保持谨慎的原因。

这就是为什么name asc是允许的,因为它是简单的属性参数。而LOWER(name) asc正在抛出警告,因为它不是简单的属性参数,对此参数有一个方法调用,可能用于 SQL 注入(inject)。(显然,攻击者可能不会使用简单的 LOWER 函数进行攻击,而是会使用一些特殊的函数,也许是他在以前的某个甚至相同的调用中用类似的注入(inject)方法定义的)。

关于ruby-on-rails - Rails 5.2.3 上的危险查询方法弃用警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56717592/

相关文章:

ruby-on-rails - Rails 和 <span> 标签

ruby-on-rails - 从一系列 Rake 任务中退出并继续下一个

php - 我的 mysqli 代码有什么问题?

java - Order By 之后的 SQL 注入(inject)

ruby-on-rails - 创建具有 has_one 关系的 FactoryBot 用户

ruby-on-rails - Rails : How to mock gems, 如 fb_graph

ruby-on-rails - 我如何找出 Rails 下载及其安装的大小?

entity-framework - IQueryable SQL 注入(inject)证明是否使用 Entity Framework ?

rails-activestorage - Rails 5 ActiveStorage 中的图像优化

ruby-on-rails - 弃用警告 : Dangerous query method: Random Record in ActiveRecord >= 5. 2