カテゴリ: Rails 更新日: 2026/02/03

Railsのセキュリティ強化!初心者でもわかるヘッダー設定・リファラ検証・オープンリダイレクト対策

セキュリティ強化:ヘッダー設定・リファラ検証・リダイレクトオープンリダイ対策
セキュリティ強化:ヘッダー設定・リファラ検証・リダイレクトオープンリダイ対策

先生と生徒の会話形式で理解しよう

生徒

「Webアプリを作るとき、セキュリティって何をすればいいんですか?」

先生

「とても大切なポイントですね。Railsでは、いくつかの基本的なセキュリティ対策が必要です。」

生徒

「たとえば、どんな対策があるんですか?」

先生

「たとえば、HTTPヘッダーの設定、リファラの検証、そしてリダイレクト時のURLチェックなどがあります。ひとつずつ一緒に学んでいきましょう。」

1. HTTPヘッダーを使ってRailsアプリを守ろう

1. HTTPヘッダーを使ってRailsアプリを守ろう
1. HTTPヘッダーを使ってRailsアプリを守ろう

まずは、HTTPヘッダーの設定から始めましょう。HTTPヘッダーは、Webブラウザとサーバーの間でやり取りされる情報のことです。ここでセキュリティに関するルールを決めることができます。

Railsでは、config/initializersに設定ファイルを作成することで、HTTPヘッダーを制御できます。

たとえば、クリックジャッキングという攻撃を防ぐには、次のような設定を追加します。


# config/initializers/security_headers.rb
Rails.application.config.action_dispatch.default_headers.merge!({
  'X-Frame-Options' => 'SAMEORIGIN'
})

この設定により、自分のサイト以外からの<iframe>での読み込みを防ぐことができます。悪意のあるサイトに埋め込まれて、ユーザーが誤って操作してしまう危険を防げます。

2. リファラ検証で不正アクセスを防ぐ

2. リファラ検証で不正アクセスを防ぐ
2. リファラ検証で不正アクセスを防ぐ

次に、リファラ(Referer)をチェックする方法を紹介します。リファラとは、「どこからアクセスしてきたのか」という情報のことです。

たとえば、自分のフォームから送信されたはずのデータが、外部サイトから送られてきた場合、それは不正なリクエストかもしれません。

これを防ぐために、コントローラでリファラを検証するコードを追加できます。


before_action :check_referer, only: [:create, :update]

private

def check_referer
  unless request.referer&.start_with?(root_url)
    render plain: "不正なアクセスです", status: :forbidden
  end
end

このコードでは、refererが自分のアプリから来ていない場合に、処理を拒否しています。これによって、外部からの不正なPOST送信をブロックできます。

3. オープンリダイレクト攻撃とは?その対策方法

3. オープンリダイレクト攻撃とは?その対策方法
3. オープンリダイレクト攻撃とは?その対策方法

最後に紹介するのは、オープンリダイレクトという攻撃と、その防ぎ方です。

ログイン後に元のページへ戻す機能などで、URLをパラメータとして受け取ることがあります。


redirect_to params[:return_to]

このようなコードでは、悪意のあるURLが指定されてしまうと、ユーザーが外部の偽サイトに誘導されてしまいます。たとえば、パスワードを盗むような危険なサイトです。

これを防ぐには、リダイレクト先のURLが自分のサイト内であるかをチェックする必要があります。


def safe_redirect(target)
  uri = URI.parse(target)
  if uri.host.nil? && uri.path.start_with?('/')
    redirect_to target
  else
    redirect_to root_path, alert: "不正なリダイレクトです"
  end
end

この方法では、hostが空(つまり外部サイトではない)で、pathがスラッシュから始まっているかを確認しています。これで、外部へのリダイレクトを防ぐことができます。

4. まとめて覚えよう!セキュリティの基本ポイント

4. まとめて覚えよう!セキュリティの基本ポイント
4. まとめて覚えよう!セキュリティの基本ポイント

ここまで、Railsでできるセキュリティ対策のうち、基本的かつ重要な3つのポイントを解説しました。

  • HTTPヘッダーの設定でクリックジャッキングを防ぐ
  • リファラ検証で外部からの不正なリクエストを防ぐ
  • オープンリダイレクト対策で外部サイトへの誘導を防ぐ

セキュリティは「あとでやろう」と思ってしまいがちですが、最初から設計に組み込むことが大切です。Railsではbefore_actionなどのフィルタを使って、こうした対策をアクションの前に自動で実行することができます。

一見難しそうに見えるこれらの対策も、「自分のアプリを守るおまじない」として習慣づけていけば、自然と身についていきますよ。

まとめ

まとめ
まとめ

ここまで、Ruby on Railsにおける主要なセキュリティ対策について詳しく解説してきました。Webアプリケーションを公開する上で、セキュリティは決して無視できない要素です。特に今回取り上げた「HTTPヘッダー」「リファラ検証」「オープンリダイレクト対策」は、ユーザーの個人情報や信頼を守るための第一防衛ラインとなります。

Railsセキュリティの重要キーワード

セキュリティ対策を実装する際には、ただコードをコピーするのではなく、その攻撃が「どのような仕組みで、どのような被害をもたらすのか」を理解することが大切です。

  • クリックジャッキング対策: X-Frame-Optionsを設定することで、透明なiframeを用いたなりすまし操作を防ぎます。現代のブラウザではContent-Security-Policy (CSP)の利用も推奨されますが、まずはこの基本を押さえましょう。
  • リファラ検証: request.refererを利用して、正規の画面遷移を経てリクエストが送られているかを確認します。CSRF(クロスサイトリクエストフォージェリ)対策の補助としても有効な手段です。
  • オープンリダイレクト対策: ユーザーを外部のフィッシングサイトなどへ意図せず転送させないための仕組みです。redirect_back_or_defaultなどのRails標準機能を活用しつつ、動的なURLを受け取る際は必ず検証を行いましょう。

応用:データベースと連携したログ記録

セキュリティインシデント(不正アクセスの試行など)が発生した際、その履歴をデータベースに保存しておくことも実務では重要です。例えば、不正なリファラや不正なリダイレクト先が指定された場合、それを「警告ログ」としてテーブルに記録する仕組みを考えてみましょう。

まず、不正アクセスを記録するためのaccess_logsテーブルの例を確認します。


id | ip_address   | user_id | alert_type        | attempted_url | created_at
---+--------------+---------+-------------------+---------------+--------------------
1  | 192.168.1.5  | 10      | invalid_referer   | /login        | 2026-01-30 10:00:00
2  | 203.0.113.42 | nil     | open_redirect     | http://evil.com| 2026-01-30 11:20:00
3  | 192.168.1.10 | 5       | none              | /dashboard    | 2026-01-30 12:05:00
4  | 172.16.0.1   | nil     | xss_attempt       | /search?q=<    | 2026-01-30 13:15:00
5  | 192.168.1.15 | 8       | invalid_referer   | /profile      | 2026-01-30 14:40:00

次に、SQLを用いて「重大な警告(alert_typeがnone以外)」が発生しているログのみを抽出するクエリを実行します。


SELECT id, ip_address, alert_type, attempted_url
FROM access_logs
WHERE alert_type != 'none'
ORDER BY created_at DESC;

実行結果は以下のようになります。


id | ip_address   | alert_type      | attempted_url
---+--------------+-----------------+-------------------
5  | 192.168.1.15 | invalid_referer | /profile
4  | 172.16.0.1   | xss_attempt     | /search?q=<
2  | 203.0.113.42 | open_redirect   | http://evil.com
1  | 192.168.1.5  | invalid_referer | /login

Ruby on Railsでの実装サンプル

では、実際にオープンリダイレクトを防ぎつつ、不正なアクセスを検証するロジックをより堅牢に記述してみましょう。RailsのURIモジュールを活用した安全なリダイレクト処理のクラス実装例です。


class SecurityChecker
  def self.safe_url?(url, host)
    return false if url.blank?
    
    uri = URI.parse(url)
    # 外部ホストが含まれていない、かつパスが正しくスラッシュで始まっているか
    # あるいは自社ドメインと完全に一致しているかを確認
    uri.host.nil? && uri.path.start_with?('/') || uri.host == host
  rescue URI::InvalidURIError
    false
  end
end

# コントローラでの利用例
def destination_redirect
  target = params[:next_page]
  
  if SecurityChecker.safe_url?(target, request.host)
    redirect_to target
  else
    # 不正な場合はログに記録するなどの処理を入れる
    logger.warn "潜在的なオープンリダイレクト攻撃を検知: #{target}"
    redirect_to root_path, alert: "指定された遷移先は無効です。"
  end
end

セキュリティは一度設定して終わりではありません。新しい攻撃手法が日々生まれているため、Railsのバージョンを常に最新に保つことや、定期的にbundle auditなどのツールを実行してライブラリに脆弱性が含まれていないかチェックすることも忘れないでください。 基礎をしっかり固めることが、最終的には開発スピードの向上とサービスへの信頼に繋がります。

先生と生徒の振り返り会話

生徒

「先生、まとめを読んで改めてセキュリティの幅広さを感じました。HTTPヘッダー1つで、あんなに強力な『クリックジャッキング』対策ができるなんて驚きです!」

先生

「そうですね。ブラウザに『このサイトは他のサイトの枠(iframe)の中では表示させないでね』と伝えるだけで、多くの危険を回避できるんです。シンプルですが非常に効果的ですよ。」

生徒

「リファラ検証についても、以前はあまり意識していませんでした。どこから来たかを確認することで、悪意のある外部サイトからの勝手なデータ送信を防げるんですね。」

先生

「その通りです。ただ、リファラはブラウザの設定やプロキシによって送られない場合もあるので、Rails標準のCSRF対策トークン(authenticity_token)と組み合わせて使うのがベストですね。」

生徒

「オープンリダイレクトについても、自分が作ったログイン機能で同じような実装をしていたので、すぐに修正しなきゃと思いました。外部URLをそのまま redirect_to に渡すのは本当に危ないんですね。」

先生

「素晴らしい気づきです!ユーザーを騙して偽のログインページに飛ばす手法は今でも多いですからね。紹介した URI.parse を使ったチェックや、Rails 7以降であれば allow_other_host: false オプションを使うのも手ですよ。」

生徒

「最新のRailsの機能もチェックしてみます!あと、SQLでログを管理する話もありましたが、異常なアクセスを可視化しておくと、万が一の時に原因を特定しやすそうですね。」

先生

「ええ。防御するだけでなく、『何が起きているか』を把握することもエンジニアの重要な仕事です。これからも、安全で楽しいアプリ開発を続けていきましょうね。」

生徒

「はい!まずは自分のアプリの security_headers.rb を見直すところから始めてみます。ありがとうございました!」

関連記事:
カテゴリの一覧へ
新着記事
New1
Ruby
“すべてはオブジェクト”を体感!初心者向けRubyのオブジェクト指向入門【irbで学ぶ】
New2
Ruby
Rubyの標準入出力を完全ガイド!puts・print・pの違いとデバッグ活用法
New3
Ruby
Gemとは?RubyGemsとBundlerを初心者向けに完全解説!依存関係管理も図解でわかりやすく理解
New4
Ruby
Rubyの文字エンコーディング入門!UTF-8・マジックコメント・外部/内部エンコーディングを完全解説
人気記事
No.1
Java&Spring記事人気No1
Ruby
Rubyのreduceとinject入門!合計計算や集計を初心者向けに分かりやすく解説
No.2
Java&Spring記事人気No2
Ruby
Rubyの文字列エンコーディング完全ガイド!Encoding・force_encoding・encodeを初心者向け解説
No.3
Java&Spring記事人気No3
Ruby
Rubyの始め方ガイド:インストールから最初のHello Worldまで(Windows/Mac/Linux)
No.4
Java&Spring記事人気No4
データベース
PostgreSQLのWHERE句を徹底解説!初心者でもわかるSQLデータ抽出の基本
No.5
Java&Spring記事人気No5
Ruby
Rubyのfind/detect/find_indexを徹底解説!目的のデータを素早く探す方法
No.6
Java&Spring記事人気No6
Ruby
Rubyで比較演算子を完全解説!==・===・<=>・eql? の使い分け
No.7
Java&Spring記事人気No7
Ruby
Rubyのselect/reject/filterの使い方を完全解説!初心者向けの条件抽出レシピ
No.8
Java&Spring記事人気No8
データベース
PostgreSQLで順位付け!ROW_NUMBER関数の使い方を初心者向けに徹底解説