LoginSignup
10
9

More than 5 years have passed since last update.

ActiveRecordのSanitization 初心者→中級者へのSTEP19/25

Last updated at Posted at 2018-12-19

はじめに

前回、sanitizeについて書きましたね。そしたら、「ActiveRecordのsanitizeも書くのじゃ」という神のお告げがあったので書きます。

 SQLインジェクションとは

前回はXSSでしたが今回はSQLインジェクションです。こちらも悪意ある攻撃です。パラメータを操作してデータベースクエリに影響を与える攻撃です。
find,find_byなどは自動的に対策がされてますが、whereやsqlを生で書く場合がある時、パラメータはちゃんとサニタイズする必要があります。

sanitize_sql_array

sql = ActiveRecord::Base.send(
  :sanitize_sql_array,
  ['SELECT * from users WHERE name=?', "tarou"]
)

Rails5.1系ではsanitize_sql_arrayはパブリックではないので、上記のようにsendを使ってサニタイズします。(Rails5.2系ではパブリックになったらしいです。→https://techracho.bpsinc.jp/hachi8833/2018_08_13/60583)
また他にも、where句用のsanitize_sql_for_conditions、order句用のsanitize_sql_for_order,like用のsanitize_sql_likeがあります。

irb(main):010:0> sql = ActiveRecord::Base.send(
irb(main):011:1*   :sanitize_sql_array,
irb(main):012:1*   ['name=?', 'tarou']
irb(main):013:1> )
=> "name='tarou'"
irb(main):014:0> User.where(sql)
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE (name='tarou') LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<User id: 10, created_at: "2018-12-19 13:42:23", updated_at: "2018-12-19 13:42:23", name: "tarou">]>

まとめ

セキュリティ系調べてるとSQL力の足りなさを痛感....
とりあえずユーザーが入力するパラメータを使ったsql文を使うときはサニタイズを意識しておきましょう。

参考にしたの

ActiveRecord::Sanitization::ClassMethods
https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html

Rails セキュリティガイド
https://railsguides.jp/security.html#sql%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9