動かざることバグの如し

近づきたいよ 君の理想に

Railsで生SQL実行時にプレースホルダー付けてSQLインジェクション対策

環境

やりたいこと

RailsActiveRecordの生成するSQLではなく、生SQL実行したいときは以下のようにしてできる。

ActiveRecord::Base.connection.execute("select count(1) from users where date = '2018-10-20'")

が、プレースホルダー機能を使おうとするとエラーになる。

# not work
ActiveRecord::Base.connection.execute("select count(1) from users where date = ?", "2018-10-20")

実はActiveRecord::Base.connection.executeではプレースホルダーによるエスケープは使えない。残念。。。

なんとかしてエスケープする

ActiveRecordsanitize_sql_arrayを使う 例えば以下のような感じ

sql = ["select count(1) from users where date = ?", "2018-10-20"]
sanitized_sql = ActiveRecord::Base.send(:sanitize_sql_array, sql)
ActiveRecord::Base.connection.execute(sanitized_sql)

これでめでたくSQLインジェクション対策ができる やったね

他の方法