この記事は、脆弱性のひとつである「権限昇格(権限のないリソースへのアクセス)」について書いています。
Railsのようなフレームワークも、SQLインジェクションやXSS等のセキュリティ対策はしてくれますが、権限昇格については自分でコードを書いて対策する必要があります。
脆弱性の解説
権限昇格とは、ユーザーが本来アクセスできてはいけないデータに、不正な操作でアクセスできてしまう脆弱性のことです。
不正な操作の例として、idなどのパラメーターを変更することで本来アクセスできてはいけないデータにアクセスできてしまうというものがあります。
公式のRailsガイドに以下のような記載があります。
たった1つのパラメータを変更しただけで、ユーザーが不正な権限でアクセス可能になることがあります。パラメータは、たとえどれほど難読化・隠蔽したとしても、変更される可能性が常にあることを肝に銘じてください。
6.6 権限昇格
具体的な例として、ユーザーのプロジェクトを管理できるアプリを作っているとします。
プロジェクトの詳細を参照するために、コードを書いたとしましょう。
@project = Project.find(params[:id])
全プロジェクトから指定したidのプロジェクトを参照しています。
アプリによっては問題にならない可能性もありますが、ユーザーが全プロジェクトを参照する権限を持っていない場合は問題になります。
params[:id]は、URLに対応しているため変更できます。
ユーザーがidを50にすれば、本来アクセスできないプロジェクトを参照できてしまいます。
そのため、プロジェクトへのアクセス権を追加する必要があります。
解決方法
プロジェクトのアクセスを制限しましょう。
deviseなどを使っていて、current_userメソッドが使えるなら以下のように修正します。
@project = current_user.projects.find(params[:id])
これにより、ログインユーザーのプロジェクトから指定したidのプロジェクトを参照します。
悪意のあるユーザーがURLを変更してidを50にしても、ログインユーザーのプロジェクトの範囲から取得するため、404になります。
セキュリティ対策に使えるGem
権限管理やセキュリティ対策に便利なgemを紹介します。
pundit (おすすめ)
punditは認可を実装するためのgemです。
ポリシークラスを作成することで、シンプルな記述で認可ルールを定義し、アプリに組み込むことができます。
ポリシークラス内には、リソースに関連する各アクションに対してポリシーメソッドを定義します。ポリシーメソッドでは、ユーザーの権限やロールに基づいてアクセスを許可または拒否するロジックを記述します。
class ProjectPolicy < ApplicationPolicy
def show?
user.admin? || record.user_id == user.id
end
end
cancancan
cancancanも認可を実装するためのgemです。
アビリティクラスを作成して、ユーザーの権限とリソースに対する操作の許可または拒否のルールを定義します。
アビリティクラス内には、ユーザーのアクセス権限に対するルールを定義します。ルールは、特定のアクションやリソースに対して許可または拒否のロジックを記述します。
class Ability
include CanCan::Ability
def initialize(user)
can :read, Project, public: true
return unless user.present? # additional permissions for logged in users (they can read their own posts)
can :read, Project, user: user
return unless user.admin? # additional permissions for administrators
can :read, Project
end
end
brakeman (おすすめ)
brakemanはセキュリティスキャンを実行するためのgemです。
ソースコードをスキャンして、潜在的なセキュリティリスクを特定します。
例えば、クロスサイトスクリプティング(XSS)、SQLインジェクション、不正なマスアサインメント、不正なリダイレクトなどの問題を検出します。
GithubActionsなどのCIで実行させるのが良いです。
name: Ci
on:
pull_request:
branches:
- '*'
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
bundler: default
bundler-cache: true
- name: Install dependencies
run: |
sudo apt-get install -y -qq libvips
- name: Brakeman Check
run: bundle exec brakeman
まとめ
- 権限昇格は、ユーザーが本来アクセスできてはいけないデータに、不正な操作でアクセスできてしまう脆弱性のこと
- アクセス権限を確認して、データの範囲を限定すること
- gemやCIを利用して脆弱性の対策ができる
権限昇格は気をつけていても、起きてしまうものです。
データへのアクセスが適切かどうか常に確認するようにしましょう。
スポンサーリンク