web-dev-qa-db-ja.com

RailsでSQLフラグメントをサニタイズする方法

SQLクエリの一部をサニタイズする必要があります。私はこのようなことができます:

class << ActiveRecord::Base
  public :sanitize_sql
end

str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')

しかし、保護されたメソッドを公開しているため、安全ではありません。それを行うためのより良い方法は何ですか?

38
dimus

あなたはただ使うことができます:

ActiveRecord::Base::sanitize(string)
43
HashDog Team

ActiveRecord::Base.connection.quoteはRails 3.xでトリックを行います

16
dimus

この質問は、答えがActiveRecordからのものである必要があることを指定していません。また、Railsのバージョンである必要があります。その理由です(そのため、トップといくつかの)Railsでパラメーターをサニタイズする方法に関する回答...


ここでRails 4で動作するソリューション:

ActiveRecord::Sanitization::ClassMethodsにはsanitize_sql_for_conditionsと他の2つのaliasesがあります。sanitize_conditionssanitize_sql =。 3つは文字通りまったく同じことを行います。

sanitize_sql_for_conditions

SQL条件の配列、ハッシュ、または文字列を受け入れ、それらを有効なSQLフラグメントWHERE句の場合にサニタイズします。

また、ActiveRecordには

sanitize_sql_for_assignment

SQL条件の配列、ハッシュ、または文字列を受け入れ、それらを有効なSQLフラグメントSET句の場合にサニタイズします。

  • 上記のメソッドはデフォルトでActiveRecord :: Baseに含まれており、したがって、すべてのActiveRecordモデルに含まれていますです。

docs を参照


また、ただし、ActionControllerにはActionController::Parametersがあり、

一括更新のためにホワイトリストに登録する属性を選択し、公開すべきでない属性を誤って公開しないようにします。この目的で2つのメソッドを提供します:requireおよびpermit

params = ActionController::Parameters.new(user: { name: 'Bryan', age: 21 })
req  = params.require(:user) # will throw exception if user not present
opt  = params.permit(:name)  # name parameter is optional, returns nil if not present
user = params.require(:user).permit(:name, :age) # user hash is required while `name` and `age` keys are optional

「パラメーターマジック」は強力なパラメーター( docs here )と呼ばれ、モデルに送信する前にコントローラーのパラメーターをサニタイズするために使用できます。

  • 上記のメソッドは、デフォルトでActionController::Baseおよびしたがって、Railsコントローラに含まれています。

Railsを学び、わかりやすく説明するだけで、それが誰にも役立つことを願っています! :)

9
Bryan Dimas

間接的に呼び出すことで、メソッドのprotectednessをバイパスできます。

str = ActiveRecord::Base.__send__(:sanitize_sql, ["AND column1 = ?", "two's"], '')

...少なくとも、そのメソッドをpublicに作り直す必要がなくなります。

(あなたが実際にこれを行う必要があるのは少し疑わしいですが、上記はうまくいきます。)

5
pilcrow

Rails 5以降、推奨される方法は次のとおりです:ActiveRecord::Base.connection.quote(string)

ここで述べたように: https://github.com/Rails/rails/issues/28947

ActiveRecord::Base::sanitize(string)は廃止されました

4
Lucian Tarna

SQL WHERE条件のサニタイズに関しては、最善の解決策sanitize_sql_hash_for_conditions であったことに注意してください。 IS NULL の代わりに = NULL(nil属性が渡された場合)。

何らかの理由で、Rails 5で非推奨になりました。そのため、将来の保証バージョンをロールバックしました。ここを参照してください: https://stackoverflow.com/a/53948665/16567

0
Yarin