Rails 4清理用户输入

7

我目前正在使用Ruby on Rails制作API。我想知道是否有内置的Rails方法或者库/宝石来对Json和SQL进行净化,或者Rails 4是否默认提供这项功能?我最担心的情况是当我有一个SQL语句时,例如:

User.where("users.first_name IS NOT NULL") 

或类似于某种东西。
Event.where(:location => params[:location]). 

在我的SQL语法和传入的JSON请求中,我应该注意什么?

2个回答

13

默认情况下,使用以下内容将对 str 进行净化并使其免受SQL注入的影响:

User.where(name: str)
User.where('name ILIKE ?', str)

然而,以下代码(直接字符串插值然后传递给where方法)使其容易受到SQL注入攻击的威胁:

User.where("name = '#{str}'")

在您的情况下,您可以使用ActiveRecord :: Base.sanitize(your_string_from_user_input)。它将使用您的DB适配器来转义/引用相关部分,从而防止SQL注入
在模型中,您可以直接访问sanitize方法(因为您已经处于继承自ActiveRecord :: Base的上下文中):
class User < ActiveRecord::Base

  def self.search(string)
    terms = string.split
    searchable_columns = [:name, :username, :whatever]
    query = terms.map do |term|
      fields = searchable_columns.map |column|
        " #{self.table_name}.#{column} LIKE '#{sanitize("%#{term}%")}'"
      end
      "(#{fields.join(' OR ')})"
    end.join(' AND ')

    where(query)
  end
end

以上代码将生成一个类似于以下的 SQL WHERE 子句:

# str is 'bob doe'
WHERE 
  (users.name LIKE 'bob' OR users.username LIKE 'bob' OR users.whatever LIKE 'bob')
AND
  (users.name LIKE 'doe' OR users.username LIKE 'doe' OR users.whatever LIKE 'doe')

这是一个不错的解决方案。 - j-dexx
谢谢,这太棒了! - timmy

10

如果您正确格式化查询,Rails会自动执行它。

来自指南 - 不要做以下事情:

Project.where("name = '#{params[:name]}'")

相反,执行以下操作

Project.where("name = ?", params[:name])

1
关于插值符号的问题,你说得很好,但我不确定 Event.where(:location => params[:location]). 是否会被过滤。 - max pleaner
1
@maxpleaner 这会很有用 - 在指南页面的下方 - j-dexx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接