ruby-on-rails 这是否容易受到sql注入的攻击?

wkftcu5l  于 2023-02-10  发布在  Ruby
关注(0)|答案(1)|浏览(164)

在寻找解决我的问题的方法时,我发现了这个主题:
Rails and Arel and Scopes - simplify multiple OR's on the same table/field match
答案之一是这样的:

fields = ["name", "email", "phone", "business_name", "doc_id"]
filter = fields.map { |field| "lower(#{field}) LIKE '#{term.downcase}'" }.join(' OR ')
@customers = Customer.where(filter)

但是如果term是用户输入的参数,这不是容易受到sql注入的攻击吗?如果是这样,我怎样才能使它不受sql注入的攻击呢?sanitize_sql_like会修复sql注入问题吗?就像这样:

filter = fields.map { |field| "lower(#{field}) LIKE '#{sanitize_sql_like(term.downcase)}'" }.join(' OR ')
@customers = Customer.where(filter)

更新:这是解决方案吗?

fields = ["name", "email", "phone", "business_name", "doc_id"]
filter = fields.map { |field| "lower(#{field}) LIKE :query" }.join(' OR ')
@customers = Customer.where(filter, query: "%#{sanitize_sql_like(term.downcase)}%")
bz4sfanl

bz4sfanl1#

任何将用户输入插入到SQL字符串中的情况都是潜在的SQL注入漏洞。逃避输入(sanitize_sql_like的作用)可以在一定程度上缓解该漏洞,但最好使用绑定变量将用户输入单独传递到数据库,这样就不会被误解为实际命令。

# bad
User.where("email like %#{params[:email]}%")

# good
User.where("email like ?", "%#{params[:email]}%")

您也不需要手动构造那个庞大的SQL字符串,而只需创建一个ActiveRecord::Relations数组,并使用.or方法将它们连接在一起。

fields = %w{ name email phone business_name doc_id }
filters = fields.map do |field|
  Customer.where("lower(#{field}) LIKE :term", term: term.downcase)
end
@customers = filters.drop(1).inject(filters.first) do |memo, scope|
  memo.or(scope)
end

这可能看起来有些令人生畏,但它实际上只是一个花哨的裤子版本:

Customer.where("lower(name) LIKE :term", term: term.downcase)
        .or(
          Customer.where("lower(email) LIKE :term", term: term.downcase)
        )
        .or(
          Customer.where("lower(phone) LIKE :term", term: term.downcase)
        )
        # ...

相关问题