12

可能であれば、バグのある可能性のある独自の正規表現を手動で作成することなく、ユーザー入力を含む文字列をサニタイズしようとしていますが、それが唯一の方法である場合は、誰かが私を正しい方向に向けることができれば幸いです。何かが欠けている可能性が低い正規表現。Railsには、ネイティブSQLコマンドを入力できるメソッドがいくつかありますが、それらのユーザー入力をどのようにエスケープするのでしょうか。

私が尋ねている質問は幅広いものですが、私の特定のケースでは、Railsが私が知る限りネイティブに理解していないPostgresデータベースの列、プレーンテキスト検索情報を保持するtsvectorを使用しています。Railsは文字列のように読み書きできますが、文字列とは異なり、モデル内でvector =のようなことをすると、自動的にエスケープされないようです。

たとえば、model.name ='::'を実行すると、nameは文字列であり、正常に機能します。model.vector ='::'を実行すると、エラーが発生します。

ActiveRecord::StatementInvalid: PGError: ERROR:  syntax error in tsvector: "::"
"vectors" = E'::' WHERE "id" = 1

これはセミコロンのエスケープの欠如によって引き起こされた問題のようであり、手動でvector='::'を設定できます。

私も素晴らしい考えを持っていました、多分私はちょうど次のようなものを呼ぶことができます:

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::"

ただし、この構文は機能しません。これは、生のSQLコマンドが、?を使用して文字列をエスケープおよび入力するfindのメソッドにアクセスできないためです。マーク。

これは、あらゆるタイプのユーザー入力でconnection.executeを呼び出すのと同じ問題になります。これは、すべて文字列のサニタイズに帰着するためですが、RailsのSQL文字列サニタイズメソッドを手動で呼び出す方法が見つからないようです。誰かアドバイスはありますか?

4

1 に答える 1

17

このメソッドをモデルに追加します。

class Media < ActiveRecord::Base
  def self.execute_sql(*sql_array)     
    connection.execute(send(:sanitize_sql_array, sql_array))
  end
end

これで、次のような任意のSQLを実行できます。

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::')

参照

1)sanitize_sql_array

于 2010-03-23T06:28:35.863 に答える