【Rails 7】ActionController::Redirecting::UnsafeRedirectErrorが出た時の対応
はじめに
こんにちは。現在プログラミングスクールでRuby on Railsを学習しているmockeyです。
卒業制作にて海外旅行初心者向けの準備アプリを作成しており、その中でユーザーに公式LINEからリマインド通知を送る機能を実装しています。
実装中に表題のエラーが起こったため、備忘録としてこの記事で取り扱うことにしました。
何か少しでも参考になることがあれば幸いです。
前提
この記事ではエラーの内容に焦点を当てているので、LINE通知機能についての説明は割愛いたします。
ご了承くださいませ。
記事のゴール
- ActionController::Redirecting::UnsafeRedirectErrorがどういうエラーなのかを知る
- ActionController::Redirecting::UnsafeRedirectErrorが出た時の対処法が分かる
環境
- ruby 3.2.3
- rails 7.1.3.4
エラーの発生箇所
line_auth_controllerについて
LINEのユーザーとアプリケーションユーザーの紐付け処理のためのコントローラー。
LINEログインを通じて取得したユーザーIDをアプリのcurrent_userに紐付けする。
エラー発生時の該当コード
class LineAuthController < ApplicationController
def link
redirect_to line_login_url
end
~~~~~~~~~省略~~~~~~~~~~~~~
private
def line_login_url #LINE認証ページのURLを生成
client_id = ENV['LINE_LOGIN_CHANNEL_ID']
redirect_uri = line_auth_callback_url
state = SecureRandom.hex(10) #CSRF対策のためのstateパラメータ
scope = "profile openid" #プロフィール情報を取得するためのスコープ
bot_prompt = "aggressive" #LINEログイン画面でのユーザーへのプロンプト表示
"https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id=#{client_id}&redirect_uri=#{redirect_uri}&state=#{state}&scope=#{scope}&bot_prompt=#{bot_prompt}"
end
エラー内容
UnsafeRedirectError
という名前からして何やら不安全であることが読み取れるエラーですね。
エラーの調査
ActionController::Redirecting::UnsafeRedirectError
について調べたところ、以下の内容であることが判明しました。
Railsガイドによると、Rails 7.0以降では外部ホストへのリダイレクト(オープンリダイレクト)がデフォルトで制限されています。
オープンリダイレクトのリスク
オープンリダイレクト脆弱性とは、ウェブサイトが適切にチェックされていない入力をもとに、ユーザーを別の悪質なサイトに誘導してしまう問題です。
この脆弱性を悪用することで、攻撃者はユーザーを騙して、自分の情報を攻撃者に提供させたり、フィッシング詐欺に巻き込んだりすることができます。例えば、信頼できるサイトと見せかけたリンクをクリックさせ、実際には危険なサイトに飛ばしてしまうなど。
これにより、ユーザーは自分が安全だと思っている情報を、知らずに攻撃者に渡してしまう危険があります。
config.action_controller.raise_on_open_redirects
は、Railsの設定の一つ。
アプリケーションが外部のURLにリダイレクトされるのを防ぐために使われます。
バージョン | デフォルト値 |
---|---|
オリジナル | false |
7.0以降 | true |
-
Rails 7以降はデフォルトでtrueに設定されている
つまり外部リダイレクトが自動的に防がれるので、外部ホストを含むURLがredirect_to
に渡されるとActionController::Redirecting::UnsafeRedirectError
が発生します。
今回の場合、line_login_url
メソッドが生成しているURLは、LINEの認証ページへの外部URLです。
具体的には、https://access.line.me/oauth2/v2.1/authorize~~
というURLが外部ホストにあたるので、Railsの設定によってリダイレクト時にエラーが発生しました。
- 500エラーについてはこちらの記事で詳しく書いてありましたので割愛します。
解決方法
Railsガイドによると、外部ホストを含むURLを許可する際はredirect_to
の呼び出しにallow_other_host: true
オプションを追加する必要があります。
修正後のコード
def link
redirect_to line_login_url, allow_other_host: true #追加
end
終わりに
今回は外部ホストを含むURLをリダイレクトした際のエラー対応について紹介しました。
Google認証を実装した際はこの様なエラーがなかったのですが、GPTによると以下の様な回答がありました。しかし、参考文献が見つけられていないので、引き続き調査しようと思います。
よく使われる認証サービス(例: Google、Facebook)は、通常、ホワイトリストに追加されており、これらへのリダイレクトは問題なく許可されることが多い
今回もご覧いただきありがとうございました。
Discussion