Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rails-brakeman对sql注入的警告_Sql_Ruby On Rails_Ruby_Sql Injection_Brakeman - Fatal编程技术网

Rails-brakeman对sql注入的警告

Rails-brakeman对sql注入的警告,sql,ruby-on-rails,ruby,sql-injection,brakeman,Sql,Ruby On Rails,Ruby,Sql Injection,Brakeman,我的模型中有一个范围: scope :assigned_to_user, ->(user) { task_table = UserTask.table_name joins("INNER JOIN #{task_table} ON #{task_table}.user_id = #{user.id} AND (#{task_table}.type_id = #{table_name}.type_id) AND (#{t

我的模型中有一个范围:

scope :assigned_to_user, ->(user) {
task_table = UserTask.table_name

    joins("INNER JOIN #{task_table}
          ON  #{task_table}.user_id = #{user.id}
          AND (#{task_table}.type_id = #{table_name}.type_id)
          AND (#{task_table}.manager_id = #{table_name}.manager_id)
        ")
}
因此,在运行brakeman报告后,我得到以下警告:

assigned_to_user | SQL Injection | Possible
因此,我尝试了以下方法:

scope :assigned_to_user, ->(user) {
    task_table = UserTask.table_name

        joins(ActiveRecord::Base::sanitize("INNER JOIN #{task_table}
              ON  #{task_table}.user_id = #{user.id}
              AND (#{task_table}.type_id = #{table_name}.type_id)
              AND (#{task_table}.manager_id = #{table_name}.manager_id)
            "))
    }
这对我不起作用,因为它在sql的前面和后面添加了
(撇号)。因此,当我将其用作返回一些结果的查询的一部分,并应用此范围时,它会生成错误的sql

我也试过:

scope :assigned_to_user, ->(user) {
    task_table = UserTask.table_name

        joins("INNER JOIN #{task_table}
              ON  #{task_table}.user_id = ?
              AND (#{task_table}.type_id = #{table_name}.type_id)
              AND (#{task_table}.manager_id = #{table_name}.manager_id)
            ", user.id)
    }

甚至没有生成语句。尝试了其他一些不起作用甚至不值得一提的东西。有人知道如何解决这个问题吗?

经过一些研究后,我会使用这里。 有一个名为
sanitize\u sql\u array
()的方法,您可以使用它通过向其传递sql字符串和替换值来转义语句,如:

sanitize_sql_array(['user_id = :user_id', user_id: 5])
# => "user_id = 5"
如果我们将一个表名传递给这个方法,它也将转义它,但将对一个值应用
ActiveRecord::Base.connection
对象的
quote
方法,该方法用于转义变量,而不是表名。有时它可能会工作,但在我使用PostrgreSQL时失败了,因为
quote
方法使用单引号,而PostgreSQL要求表名使用双引号

sanitize_sql_array([
  'INNER JOIN :table_name ON :table_name.user_id = :user_id',
  { table_name: 'users', user_id: 5 }
])
# => "INNER JOIN 'users' ON 'users'.user_id = 5"
connection
对象还有一个方法
quote\u table\u name
,该方法可以单独应用于表名,以确保它们被转义并对用户id使用
sanitize\u sql\u array

scope :assigned_to_user, -> (user) {
  task_table = connection.quote_table_name(UserTask.table_name)
  current_table = connection.quote_table_name(table_name)
  sanitized_sql = sanitize_sql_array([
    "INNER JOIN #{task_table}
    ON  #{task_table}.user_id = :user_id
    AND (#{task_table}.type_id = #{current_table}.type_id)
    AND (#{task_table}.manager_id = #{current_table}.manager_id)",
    { user_id: user.id }
  ])
  joins(sanitized_sql)
}
或者您实际上可以在
user.id
上使用
sanitize
,而不是将所有内容包装在
sanitize\u sql\u数组
方法调用中(
{sanitize(user.id)}

顺便说一下,Brakeman不会显示任何警告,因为查询已移动到变量。Brakeman按原样解析代码,它不知道变量及其内容。所以所有这一切只是为了让你自己确信一切都逃脱了

为了让Brakeman闭嘴,您可以将查询移动到一个变量:

scope :assigned_to_user, -> (user) {
  task_table = UserTask.table_name
  query = "INNER JOIN #{task_table}
          ON  #{task_table}.user_id = #{user.id}
          AND (#{task_table}.type_id = #{table_name}.type_id)
          AND (#{task_table}.manager_id = #{table_name}.manager_id)"
  joins(query)
}

谢谢你的研究。除了最后一个,其他人都工作了。刹车手仍然发现了那个。但是,如果将字符串存储在绕过警告的
%Q{..query here..}
中。虽然根据所选答案清除值总是好的,但在这种情况下,Brakeman警告是一个假阳性,将用