2012-08-26 104 views
3

在我的控制器動作,我有以下幾點:這是否容易發生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 

和模型:

​​

我明白,如果你直接在查詢中使用PARAMS SQL注入將是可能的。在這裏,我通過Article.search(params[:search])直接將params傳遞給where查詢。這是否容易SQL注入?如果是這樣,我怎樣才能讓它更安全?如果我已經正確編寫了控制器代碼,我也有疑問。如果你有重構控制器代碼的建議,請讓我知道,他們將非常感激。非常感謝!

回答

3

對於你的查詢,你應該嘗試使用ActiveRecord提供的方法或通過Arel本身(你目前的方法是好的,但)。這將確保您的SQL正確轉義。如果您現在不想進入Arel的詳細信息,則可以使用像squeelmeta_where(適用於較舊的導軌)的寶石。

我強烈推薦這些寶石,以滿足大部分查詢構建需求。更高級的任何東西都可以使用Arel直接寫出來。

我不記得,如果你可以做matchesLIKE)直接在基本的ActiveRecord.where語法,沒有gem的幫助,但呢。但你絕對可以直接在Arel中這樣做。

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

在這一點上,你可以在articlesto_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') 

的方法您現在使用必搶「ALL」的[允許]記錄然後排序,然後給回你的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的lazyloads它的數據庫查詢的方式。

+0

感謝您提供這些細節。我不確定我是否還想進入Arel,但是Squeel確實看起來很吸引人,我一定會檢查一下。按照'你現在的方法很好',你的意思是說注射安全嗎?如果可能的話,你能解釋一下那部分嗎?謝謝! – maru

+0

我知道分頁有問題,但我的問題是我無法對數組執行.page(),因爲第一行返回數組或活動記錄關係。你知道我該如何處理?通過傳遞排序選項,你的意思是我應該將它作爲參數傳遞,並對模型執行排序?謝謝。 – maru

+0

http://guides.rubyonrails.org/security.html#sql-injection,可以解釋一下比我好一些。 – nowk

相關問題