当前位置: 首页 > 面试题库 >

Rails Brakeman警告SQL注入

黄和怡
2023-03-14
问题内容

我的模型中有一个范围:

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)
        ")
}

因此,在运行刹车员报告后,我会收到以下警告:

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_sql_array(ref)的方法,您可以通过将sql字符串和替换值传递给它来转义语句,如下所示:

sanitize_sql_array(['user_id = :user_id', user_id: 5])
# => "user_id = 5"

如果我们将表名传递给此方法,它将也对其进行转义,但将在值上应用一个对象quote方法,ActiveRecord::Base.connection该值用于转义变量,但不对表名进行转义。也许有时它会起作用,但是当我使用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_table_name,可以将其单独应用于表名,以确保对它们进行转义并sanitize_sql_array用作用户ID。

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)
}

或者,您实际上可以只使用sanitizeonuser.id而不是将所有内容包装在sanitize_sql_array方法调用(#{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)
}


 类似资料:
  • 云联壹云平台支持对宿主机、虚拟机、云账号等资源的相关指标进行监控告警,告警消息支持通过机器人、邮件、短信、飞书、钉钉、企业微信等通知渠道发送给用户。 告警策略 告警策略即针对监控指标设置阈值,当资源的指标超过阈值时,将会立即通过通知渠道向用户发送告警消息,使用户可以快速响应解决问题。 告警历史 告警历史显示系统中所有的触发告警以及恢复告警的告警策略和资源信息。 告警资源 告警资源即宿主机、云账号等

  • 我正在使用python处理一些图像,并尝试将一系列大小为961x509的图像转换为MP4电影文件。我已经这样做了,它正在工作,但我有一个相当恼人的问题,警告说这样的话: 警告:根:图像FFMPEG_WRITER警告:输入图像不能被macro_block_size=16整除,大小从(509L,961L)到(512L,976L),以确保与大多数编解码器和播放器的视频兼容性。若要防止调整大小,请使输入图

  • 问题内容: 我尝试了以下代码将列转换为“日期”: 要么 但出现以下错误: /Users/xyz/anaconda3/envs/sensor/lib/python3.6/site- packages/pandas/core/indexing.py:517:SettingWithCopyWarning:试图在DataFrame的切片副本上设置一个值。尝试改用.loc [row_indexer,col_

  • 主要内容:实例,可取消的警告(Dismissal Alerts),实例,警告(Alerts)中的链接,实例本章将讲解警告(Alerts)以及 Bootstrap 所提供的用于警告的 class。警告(Alerts)向用户提供了一种定义消息样式的方式。它们为典型的用户操作提供了上下文信息反馈。 您可以为警告框添加一个可选的关闭按钮。为了创建一个内联的可取消的警告框,请使用 警告(Alerts) jQuery 插件。 您可以通过创建一个 <div>,并向其添加一个 .alert class 和四个上

  • 注:内容翻译自 官方文档Alarm Pinpoint-web周期性的检查应用的状态,如果特定前置条件(规则)满足时则触发告警。 这些条件(默认)每3分钟被web模块中的后台批处理程序检查一次,使用最后5分钟的数据。一旦条件满足,批处理程序发送短信/邮件给注册到用户组的用户。 用户指南 配置菜单 注册用户 创建用户组 添加用户到用户组 设置告警规则 告警规则 SLOW COUNT / 慢请求数 当应

  • 用于页面中展示重要的提示信息。 基本用法 页面中的非浮层元素,不会自动消失。 Alert 组件提供四种主题,由type属性指定,默认值为info。 <template> <el-alert title="成功提示的文案" type="success"> </el-alert> <el-alert title="消息提示的文案" type="info">