Rails Brakeman:Arel 的 SQL 注入
Posted
技术标签:
【中文标题】Rails Brakeman:Arel 的 SQL 注入【英文标题】:Rails Brakeman: SQL Injection for Arel 【发布时间】:2021-07-18 00:21:16 【问题描述】:我的user_ransaker.rb
文件中有以下代码:
ransacker :new_donors do
sql = %(
users.id IN (
#User.new_donor_sql
)
)
Arel.sql(sql)
end
在user.rb
模型上:
def self.new_donor_sql
part_1 = %(
SELECT distinct(user_id)
FROM donations
part_1
end
对于上述声明,我收到以下 Brakeman 警告:
Confidence: High
Category: SQL Injection
Check: SQL
Message: Possible SQL injection
Code: Arel.sql("(\n users.id IN (\n #User.new_donor_sql\n)\n)")
File: app/models/concerns/user_ransackers.rb
这是一个有效的错误吗?如果我使用 ActiveRecord 编写 SQL 语句,如果需要插入值,我可以使用 ?
占位符。我不确定如何解决此警告。如果这是一个有效的警告,我该如何补救?
【问题讨论】:
您使用 Arel 进行此查询是否有特殊原因?这可以通过 ActiveRecord 来完成。 我正在使用 Ransack gem。我正在做类似于文档中提到的第 2.2 点的事情:github.com/activerecord-hackery/ransack/wiki/Using-Ransackers。如果我使用 ActiveRecord,我会得到undefined method 'eq' for ....
【参考方案1】:
如果你要 Arel 然后做一些关系代数:
class User < ApplicationRecord
def self.new_donor_sql
arel_table.project(arel_table[:user_id]).distinct
end
end
ransacker :new_donors do
User.arel_table.then do |users|
users.where(users[:id].in(User.new_donor_sql)).where_sql
end
end
你也可以直接删除类方法:
ransacker :new_donors do
User.arel_table.then do |users|
subquery = users.project(users[:user_id]).distinct
users.where(users[:id].in(subquery)).where_sql
end
end
【讨论】:
我收到undefined method then for #<Arel::Table
您使用的是什么版本的 Ruby? Object#then
在 2.6 中作为 Object#yield_self
的别名引入 - 旧版本已停产。如果您确实必须为旧版应用程序使用旧版本,请分配一个变量而不是 users = User.arel_table; subquery = users.project(users[:user_id]).distinct; users.where(users[:id].in(subquery)).where_sql
以上是关于Rails Brakeman:Arel 的 SQL 注入的主要内容,如果未能解决你的问题,请参考以下文章