这容易出现SQL注入吗?

时间:2012-08-26 03:56:42

标签: ruby-on-rails ruby-on-rails-3 controller sql-injection

在我的控制器操作中,我有以下内容:

def index
    @articles = (params[:mine] == "true") ? current_user.articles : Article.search(params[:search])
    @articles = @articles.sort! { |a,b| b.created_at <=> a.created_at }
    @articles = Kaminari.paginate_array(@articles).page(params[:page]).per(25)

    respond_to do |format|
      format.html
      format.json { render json: @articles }
    end
end

在模型中:

  def self.search(search)
    if search.present?
      where("category LIKE ? OR article_type LIKE ?", "%#{search}%","%#{search}%")
    else
      find(:all)
    end
  end

我知道如果在查询中直接使用params,则可以进行SQL注入。在这里,我通过Article.search(params[:search])直接将params传递给where查询。这容易出现SQL注入吗?如果是,我怎样才能让它更安全?如果我正确编写了控制器代码,我也有疑问。如果您有重构控制器代码的建议,请告诉我们,我们将非常感激。非常感谢!

1 个答案:

答案 0 :(得分:3)

对于您的查询,您应该尝试使用ActiveRecord提供的方法或通过Arel本身(您当前的方法很好)。这将确保您的SQL被正确转义。如果您不想立即了解Arel的详细信息,可以使用squeelmeta_where等宝石(适用于较旧的导轨)。

我强烈建议您将这些宝石用于满足大多数查询构建需求。您可以使用Arel直接写出更高级的内容。

我记不起来了,如果你能用matches语法直接用LIKEActiveRecord.where),而不需要宝石的帮助。但你绝对可以在Arel中直接这样做。

articles = Article.arel_table
articles = articles[:category].matches("%#{search}%").
  or(articles[:article_type].matches("%#{search}%"))

此时,您可以to_a articlesto_sql使用Article并使用find_by_sql将其传递给Article.find_by_sql articles.to_sql 模型。

paginate_by_sql

will_paginate有一个kaminari方法,我认为articles.sort('`articles`.created_at DESC') 也会有一个(或至少我认为会这样)。

至于你的控制器代码,我会将任何类型的排序选项传递给数据库(这也适用于你的分页),如果可能的话。

per_page

您现在使用的方法将获取“允许”记录的“全部”然后排序,然后返回您的@articles = (params[:mine] == "true") ? current_user.articles : Article.search(params[:search]) @articles = @articles.sort('`articles`.created_at DESC').page(params[:page]).per(25) 限制。在这种情况下,哪种类型会破坏分页的目的。

至少尝试将您当前的设置重构为:

ActiveRelation

只要您传递{{1}},就可以将其他内容绑定到此,因为Rails会将其查询延伸到数据库。