対象:Ruby on Railsでアプリを運営している人。ここでは攻撃手順は扱わず、本番を固めるための実務リファレンス(優先度つきチェックリスト・領域別対策・自己検証)を示します。フレームワーク全体の考え方は フレームワーク別セキュリティの一覧 も参照。
優先度つきハードニング・チェックリスト
まずこの表を上から実施します。P0は前提、P1が最頻の事故源、P2は継続的な運用で守る項目です。
P0 ── 前提(まずこれ)
秘密とcredentialsの安全管理 / 本番設定(例外非露出・force_ssl)/ gem CVE即パッチ
P1 ── 最頻の事故源
Strong Parameters/Mass Assignment制御 / 認可(所有者スコープ)
P2 ── 継続的な運用
インジェクションと危険メソッド / セッション・CSRF / SSRF・アップロード
| 優先 | 対策 | 具体(Rails) |
|---|---|---|
| P0 | 秘密とcredentials | 暗号化 credentials+master keyを分離。master key をコミットしない。secret_key_base 漏洩はローテーション |
| P0 | 本番設定 | 例外詳細を外部に出さない・config.force_ssl・filter_parameters で機微をログ非記録 |
| P0 | gem(依存)CVE | bundler-audit / osv-scanner で監視・実稼働版で判定し即パッチ |
| P1 | Strong Parameters | permit を必要最小限に。permit! で全許可しない。権限フィールドを代入させない |
| P1 | 認可を明示 | Pundit / CanCanCan+authorize+current_user スコープで所有者確認 |
| P2 | インジェクション/危険メソッド | where はバインド。send/constantize に入力を渡さない。信頼できない YAML/Marshal を読まない |
| P2 | セッション/CSRF | protect_from_forgery(既定)・Cookie の secure/httponly/samesite・ログイン時再生成 |
| P2 | SSRF/アップロード | サーバー側取得は許可先限定+内部IP遮断。アップロードは検証し public/ 外に保存 |
1. 秘密と credentials(P0)
- Railsの暗号化 credentials を使い、master key(復号鍵)をリポジトリにコミットしない(環境変数などで注入)。
secret_key_baseは署名/暗号化Cookieやセッションに使われる鍵。漏洩したら速やかにローテーション(既存の署名/暗号化が無効化される点に注意)。.envやダンプ・バックアップを公開ディレクトリに置かない(→ 公開ディレクトリに秘密を置かない)。
2. 本番設定(P0)
- 本番では例外の詳細を外部に出さない(
consider_all_requests_localを本番で有効にしない等)。内部構造の露出を減らす。 config.force_sslでHTTPSを強制し、Cookie を secure に。開発用の web console 等を本番で有効にしない。- ログに機微が残らないよう
filter_parametersでパスワード等をフィルタする。
3. 依存(gem)のCVE(P0)
- bundler-audit や osv-scanner で gem の既知CVEを機械監視し、実稼働版(Gemfile.lock)で判定して即パッチ(→ 依存のCVE監視 / CVE対応の実務)。
- Rails と Ruby をサポート対象バージョンに保ち、EOL版を放置しない。
4. Strong Parameters と Mass Assignment(P1)
permitする項目を必要最小限にし、permit!(全許可)を避ける。is_adminのような権限フィールドをユーザー入力から代入させない。「面倒だから広く許可」をやめる。
5. 認可(P1・最多の事故源)
やりがち(危険)
- 認可を書かず「ログイン=閲覧/更新可」
- ルートモデル束縛で他人のIDでも取得できる
- 隠しただけのルート/推測しにくいIDに依存
- 一部アクションで authorize を通し忘れ
正しい
- Pundit / CanCanCan で方針を明示+各アクションで
authorize - 取得も
current_userのスコープで所有者に限定 - 取得・更新・削除のすべての経路で確認
- 認可は明示的に組み立て、既定任せにしない
用語は IDORとは。認証と認可は別物で、認可はデータに近い場所で確認します。
6. インジェクションと危険な動的メソッド(P2)
- SQL:
whereはプレースホルダでバインドし、文字列連結でクエリを組まない(where("... #{params}")を避ける)(→ SQLインジェクションとは)。 - 危険な動的メソッド:
send/public_send/constantizeにユーザー入力を渡さない。渡すなら許可リストで厳しく限定する。 - デシリアライズ:信頼できない
YAML/Marshalの読み込みは条件次第でコード実行に繋がり得るため避ける。
7. セッション・Cookie・CSRF(P2)
- **CSRF保護(
protect_from_forgery)**を全体無効化しない。フォームのトークンを活かす(→ CSRFとは)。 - Cookie/セッションに secure/httponly/samesite を設定し、ログイン時にセッションを再生成する。
8. SSRF・アップロード・ヘッダ(P2)
- サーバーがユーザー指定URLを取得する処理は許可先を限定し、内部IP/メタデータへの到達を遮断する(→ SSRFとは)。
- アップロードは種別・サイズを検証し、
public/外に保存して実行権限を与えない。 - セキュリティヘッダを付与(自サイトは セキュリティヘッダ診断 で確認)。
検証:自分のRailsは固められているか
作ったら終わりではありません。点検して初めて完了です。以下は自分の環境に対する防御的な自己チェックです。
秘密が露出/コミットされていないか
master.key がリポジトリに含まれていないこと、.envやダンプがURLで取れないことを確認。本番で例外詳細が出ないか
認可が効くか
依存とヘッダ
bundler-audit/osv がクリーンか、ヘッダ診断で HTTPS/HSTS 等が付くかを確認。当サイトの視点:既定が安全でも、認可と依存は自分の責任
Railsの良い既定は多くのリスクを減らしますが、「誰が・何を・してよいか」という認可と依存を最新に保つことだけは、アプリ固有・運用固有なのでフレームワークが自動で守れません。当サイトが繰り返し見る事故も、凝った攻撃より「認証はあるのに所有者チェックが無い」型が多い。だから重点は、上の表を上から順に実施し、Strong Parametersで受け入れる項目を絞り、認可を明示し、gemをCVE監視するという基本を徹底することです。
次に読む
- 一覧:フレームワーク別セキュリティ(一覧) / Laravelのセキュリティ対策(同じMVC・認可の注意点が近い)
- 実務:脆弱性(CVE)対応の実務 / 依存のCVE監視 / 公開ディレクトリに秘密を置かない
- 用語:IDORとは / SQLインジェクション / CSRF / SSRF
- ツール:セキュリティヘッダ診断
出典と確認範囲
以下は上記の設定・影響範囲・対策を確認するための原典です。2026年10月23日に参照先を確認しました。各版・構成の条件は原典で確認してください。チェックリストの優先順位や教訓は当サイトの整理であり、記事全体の再検証や安全性の保証を意味しません。