20

を呼び出すときに補間された文字列を使用するのは安全ではないことはわかっています.where

例:

Client.where("orders_count = #{params[:orders]}")

次のように書き換える必要があります。

Client.where("orders_count = ?", params[:orders])

を呼び出すときに補間された文字列を使用しても安全.orderですか? そうでない場合、以下はどのように書き直せばよいでしょうか?

Client.order("#{some_value_1}, #{some_value_2}")

4

5 に答える 5

19

はい、ActiveRecord の「注文」メソッド、SQL インジェクションに対して脆弱です。

いいえ、を呼び出すときに補間された文字列を使用するのは安全ではありませ.orderん。

私の質問に対する上記の回答は、http://rails-sqli.org/#orderを教えてくれたAaron Pattersonによって確認されています。そのページから:

ORDER BY 句で SQL インジェクションを利用するのは難しいですが、CASE ステートメントを使用して他のフィールドをテストし、並べ替え列を true または false に切り替えることができます。多くのクエリが必要になる可能性がありますが、攻撃者はフィールドの値を特定できます。

orderしたがって、何をしようとしても安全であることを手動で確認することが重要です。おそらく@dmcnallyの提案に似た方法を使用して。

皆さんありがとう。

于 2013-07-25T18:42:46.010 に答える
9

簡単な答えは、入力をサニタイズする必要があるということです。

補間しようとしている文字列が信頼できないソース (Web ブラウザなど) からのものである場合は、最初にそれらを信頼できる値にマップする必要があります。ハッシュを介してこれを行うことができます:

# Mappings from known values to SQL
order_mappings = {
  'first_name_asc'  => 'first_name ASC',
  'first_name_desc' => 'first_name DESC',
  'last_name_asc'   => 'last_name ASC',
  'last_name_desc'  => 'last_name DESC',
}

# Ordering options passed in as an array from some source:
order_options = ['last_name_asc', 'first_name_asc']

# Map them to the correct SQL:
order = order_options.map{|o| order_mappings[o] }.compact.join(', ')
Client.order(order)
于 2013-07-25T15:04:29.330 に答える
2

@マイクの説明は正しいです。@dmcnally 回避策が機能します。[Railscast][1] http://railscasts.com/episodes/228-sortable-table-columnsに記載されているわずかに異なるパスをたどっています

簡単に言えば、ユーザー入力をサニタイズするために、コントローラーでプライベート メソッドを構築できる場合:

  1. テーブル列の 1 つの名前で並べ替えます。

        private 
    
        def sort_column
           Client.column_names.include?(params[:sort]) ? params[:sort] : "first_name"
        end
    
  2. 他の基準で並べ替えてから、以下のようなホワイトリスト構成を使用します。

    def sort_direction
        %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
    end
    

コントローラーメソッドは次のようになります。

    Client.all.order(sort_column + " " + sort_direction)

ローマへのちょうど別の道。この助けを願っています。

于 2019-03-08T17:15:35.960 に答える
0

これを試してみましょう!

# app/models/concern/ext_active_record.rb
module ExtActiveRecord
    extend ActiveSupport::Concern

    included do
        scope :sortable, -> (params) do
            return unless params[:sort_by] && params[:sort_dir]
            reorder("#{params[:sort_by]}" => "#{params[:sort_dir]}")
        end
    end
end

# app/models/user.rb
class User < ActiveRecord::Base
    include ExtActiveRecord
    # ....
end

# app/controllers/user_controller.rb
class UserController < ApplicationController
    def index
        @users = User.sortable(params).page(params[:page]).per(params[:per])
    end
end
于 2015-05-12T09:02:10.840 に答える