这容易出现SQL注入吗?

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

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注入吗? 如果是,我怎样才能让它更安全? 如果我正确编写了控制器代码,我也有疑问。 如果您有重构控制器代码的建议,请告诉我们,我们将非常感激。 非常感谢!

对于您的查询,您应该尝试使用ActiveRecord提供的方法或通过Arel本身(尽管您当前的方法很好)。 这将确保您的SQL被正确转义。 如果你现在不想深入了解Arel细节,你可以使用像squeel或meta_where这样的gem(对于旧的rails)。

我强烈推荐这些gem,以满足您的大多数查询构建需求。 任何更高级的东西都可以直接使用Arel写出来。

我不记得了,如果你能用基本的ActiveRecord.where语法直接进行matchesLIKE ),而不需要gem的帮助。 但你绝对可以直接在Arel做到这一点。

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

此时,您可以对articles执行to_a或使用to_sql并使用find_by_sql将其传递给您的Article模型。

 Article.find_by_sql articles.to_sql 

will_paginate有一个paginate_by_sql方法,我认为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 ,就可以将其他东西绑定到此,因为Rails将它的查询延迟加载到数据库。