2

質問があります:

@results = the_db.where('name LIKE ?', '%#{input}%').paginate(
    :page => params[:page], 
    :per_page => 50, 
    :group => "name", 
    :order => [
        "CASE WHEN name like '#{input}%' THEN 0 
        WHEN name like '% %#{input}% %' THEN 1
            END, name"
    ]
)

問題は、これがインジェクションに対して脆弱であることです。(注文節) どうすればこの問題を解決できますか? ユーザーの入力を何らかの方法でサニタイズして、攻撃を無効にすることは可能ですか?

4

4 に答える 4

1

文字列を埋め込む前または後に、文字列に対してsanitizeメソッドを使用できます。inputこれは基本的に、Rails のパラメーター化が行うことです。

サニタイズすると、先頭と末尾に一重引用符が追加されることに注意してください'。必要に応じて、次のように削除できます。

sanitize(something)[1..-2] 

あなたの例では、次のことができます。

:order => [
    "CASE WHEN name like #{sanitize "#{input}%")} THEN 0 
    WHEN name like #{sanitize "% %#{input}% %")} THEN 1
        END, name"
]

sanitizeクラス メソッドまたはスコープ内で呼び出すか、それにアクセスできる名前空間を使用する必要があることに注意してください(例:ModelName.sanitizeまたはActiveRecord::Base.sanitize)。

于 2012-12-17T21:07:32.110 に答える
1

メソッドを使用できますsanitize_sql_array。残念ながら、これはプライベート メソッドであるため、 で呼び出す必要がありますsend

query = <<-QUERY
CASE WHEN name like ? THEN 0 
     WHEN name like ? THEN 1
     END, name
QUERY

sanitized_order = ActiveRecord::Base.send :sanitize_sql_array, [query, "'#{input}%'", "'% %#{input}% %'"]

@results = the_db.where('name LIKE ?', '%#{input}%').paginate(
:page => params[:page], 
:per_page => 50, 
:group => "name", 
:order => sanitized_order)
于 2012-12-17T21:12:18.470 に答える
1

パラメータ化されたクエリを使用します。

@results = the_db.where('name LIKE ?', "%#{input}%").paginate(
    :page => params[:page], 
    :per_page => 50, 
    :group => "name", 
    :order => [
        "CASE WHEN name like ? THEN 0 
        WHEN name like ? THEN 1
            END, name",
            '#{input}%',
            '% %#{input}% %'
    ]
)

文字列を持っている場合の動作はわかりませんが%

于 2012-12-17T20:59:50.947 に答える
1

squeel gem を試すこともできます:

https://github.com/ernie/squeel

Rian Bates は、彼の RailsCasts で、squeel の優れた紹介を提供しています。

http://railscasts.com/episodes/354-squeel?view=asciicast

于 2012-12-17T22:25:42.477 に答える