LoginSignup
1
0

More than 5 years have passed since last update.

Rails ActiveRecordで任意のソートカラム・順指定をセキュアに実装してみた(下書き中)

Posted at

本当にこのアプローチが正しいか検討しながら書いているのであしからず。
sanitize_sql_for_orderを使えばいいんじゃ?という説もあり

# Contorollerなどで
# SQLインジェクションできる実装
User.where(name: "Name").order(params[:f]=>params[:o])

# SQLインジェクション対策された実装
User.where(name: "Name").safe_order(params[:f], params[:o])

safe_orderメソッドは下記のように実装しています。

module SafeOrder
  extend ActiveSupport::Concern

  included do
    scope :safe_reorder, -> (key_string, order_string, **args) {
      if string = self.safe_order_string(key_string, order_string, **args)
        reorder(string)
      end
    }
    scope :safe_order, -> (key_string, order_string, **args) {
      if string = self.safe_order_string(key_string, order_string, **args)
        order(string)
      end
    }
  end

  class_methods do
    def safe_order_string(key_string, order_string, **args)
      args = {safe_keys: []}.merge args

      safe_keys = self.column_names.push(args[:safe_keys].map(&:to_s)).flatten.uniq
      _key = ([key_string.to_s.downcase] & safe_keys).first
      _order = ([order_string.to_s.downcase] & ["asc", "desc"]).first

      if _key.present? && _order.present?
        "#{_key} #{_order}"
      else
        raise "order by unknown keys" if Rails.env.development? || Rails.env.test?
        nil
      end
    end
  end
end
1
0
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
1
0