SQLクエリの一部をサニタイズする必要があります。私はこのようなことができます:
class << ActiveRecord::Base
public :sanitize_sql
end
str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')
しかし、保護されたメソッドを公開しているため、安全ではありません。それを行うためのより良い方法は何ですか?
あなたはただ使うことができます:
ActiveRecord::Base::sanitize(string)
ActiveRecord::Base.connection.quote
はRails 3.xでトリックを行います
この質問は、答えがActiveRecord
からのものである必要があることを指定していません。また、Railsのバージョンである必要があります。その理由です(そのため、トップといくつかの)Railsでパラメーターをサニタイズする方法に関する回答...
ここでRails 4で動作するソリューション:
ActiveRecord::Sanitization::ClassMethods
にはsanitize_sql_for_conditionsと他の2つのaliasesがあります。sanitize_conditionsとsanitize_sql =。 3つは文字通りまったく同じことを行います。
sanitize_sql_for_conditions
SQL条件の配列、ハッシュ、または文字列を受け入れ、それらを有効なSQLフラグメントWHERE句の場合にサニタイズします。
また、ActiveRecordには
sanitize_sql_for_assignment
SQL条件の配列、ハッシュ、または文字列を受け入れ、それらを有効なSQLフラグメントSET句の場合にサニタイズします。
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を学び、わかりやすく説明するだけで、それが誰にも役立つことを願っています! :)
間接的に呼び出すことで、メソッドのprotected
nessをバイパスできます。
str = ActiveRecord::Base.__send__(:sanitize_sql, ["AND column1 = ?", "two's"], '')
...少なくとも、そのメソッドをpublic
に作り直す必要がなくなります。
(あなたが実際にこれを行う必要があるのは少し疑わしいですが、上記はうまくいきます。)
Rails 5以降、推奨される方法は次のとおりです:ActiveRecord::Base.connection.quote(string)
ここで述べたように: https://github.com/Rails/rails/issues/28947
ActiveRecord::Base::sanitize(string)
は廃止されました
SQL WHERE条件のサニタイズに関しては、最善の解決策がsanitize_sql_hash_for_conditions であったことに注意してください。 IS NULL
の代わりに = NULL
(nil属性が渡された場合)。
何らかの理由で、Rails 5で非推奨になりました。そのため、将来の保証バージョンをロールバックしました。ここを参照してください: https://stackoverflow.com/a/53948665/16567