LoginSignup
7
3

More than 1 year has passed since last update.

ransack使用時の注意点

Last updated at Posted at 2022-12-19

この記事はRuby on Rails Advent Calendar 2022の20日目の記事です。

はじめに

ransackは検索機能を楽に実装することができるgemです。
https://github.com/activerecord-hackery/ransack

スター数は執筆時現在5.3kで、今なお開発が続けられており、人気のgemと言って差し支えないでしょう。
しかし、そのセキュリティ上の問題点についてはあまり注目されていないように感じます。
実際、執筆時現在Googleで「ransack」と検索するとセキュリティについて触れられていない記事が散見されます。
この記事ではransackのセキュリティ上の問題点とその対策について紹介します。

セキュリティ上の問題点

デフォルトで任意のカラムに対して検索ができてしまいます。1
後述の手順によってカラムの中身を特定可能です。

具体例

usersテーブルにはカラムsecret_tokenが存在するとします。
以下のような実装で、後述する対策をしていない場合に情報漏洩が起きます。

class UsersController
  # GET /users
  def index
    @records = User.ransack(params[:q]).result
  end
end

攻撃

ransackは多様なマッチャーを用意しており2、[カラム名]_startというパラメータで前方一致検索が可能です。それを利用して以下のように検索を繰り返します。

GET /users?secret_token_start=a

GET /users?secret_token_start=b

GET /users?secret_token_start=c

レコードが取得できたならばパターンに合致していたということです。
あとはこの手順を繰り返します。
ここでは先頭の文字がaだったことにして続く手順を見ていきましょう。

GET /users?secret_token_start=aa

GET /users?secret_token_start=ab

GET /users?secret_token_start=ac

2文字目以降も全く同じ工程を繰り返します。
このように非常に単純な方法で、ユーザーに公開してはいけないはずのカラムの値を特定できます。

対策

下記のようにモデルに対して検索可能なカラムのリストを設定します。

class User
  def self.ransackable_attributes(auth_object)
    %w(first_name last_name)
  end
end

こうすることで指定したカラム以外の検索を拒むことができます。

まとめ

以上のように許可リストを設定しなければ、使い方によっては情報漏洩につながることを見ていきました。ransackをお使いの方は一度実装を見直してみるといかがでしょうか。

余談

上記で述べた脆弱性について手を動かして検証できるRailsアプリを作りました。良かったら遊んでみてください。
https://github.com/wonda-tea-coffee/vulnerable_ransack_app

  1. https://activerecord-hackery.github.io/ransack/going-further/other-notes/#authorization-allowlistingdenylisting

  2. https://activerecord-hackery.github.io/ransack/getting-started/search-matches/

7
3
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
7
3