本文へスキップ
>_ITDITDセキュリティ対策プラットフォーム

フレームワーク別

Laravelのセキュリティ対策 — 本番ハードニング実務リファレンス

Laravelを本番で安全に運用するための実務リファレンス。優先度つきハードニング・チェックリスト、危険な既定設定の一覧、秘密/APP_KEY・本番設定・認可・インジェクション・セッション/CSRF・アップロード・HTTPS・依存CVEの領域別対策、そして『自分のLaravelが固められているか』の自己検証手順まで。攻撃手順は載せず防御と点検のみ。

公開日 2026-07-02 更新日 2026-07-02 12分で読める

対象:Laravelを本番で運用している人。ここでは攻撃手順は扱わず、本番を固めるための実務リファレンス(優先度つきチェックリスト・危険な既定・領域別対策・自己検証)を示します。フレームワーク全体の考え方は フレームワーク別セキュリティの入口 も参照。

優先度つきハードニング・チェックリスト

まずこの表を上から実施します。P0は他対策の前提、P1が最頻の事故源、P2は継続的な運用衛生です。

P0 ── 前提(まずこれ)

本番デバッグ無効 / 秘密を公開面の外+権限600 / APP_KEY 安全管理

P1 ── 最頻の事故源

認可(Policy/Gate) / Mass Assignment制御 / 依存CVE監視 / 本番キャッシュ

P2 ── 運用衛生

セッション/CSRF/Cookie / アップロード検証 / HTTPS・ヘッダ・レート制限

ハードニングは土台から積む。P0(前提)→P1(最頻の事故源)→P2(運用衛生)。
優先対策具体(Laravel)
P0本番デバッグ無効APP_DEBUG=false / APP_ENV=productionconfig:cache で固定。例外画面に内部を出さない
P0秘密を公開面の外へ.env・バックアップ・鍵は public/ 外。権限600。storage/logs も非公開
P0APP_KEY を安全管理暗号化・署名Cookie・セッションの土台。環境から注入・漏洩時ローテーション
P1認可を明示Policy / Gate + authorize()can ミドルウェアで所有者/権限スコープ
P1Mass Assignment 制御$fillable 明示。$request->all() の丸ごと代入を避け validated() を使う
P1依存(Composer)CVE監視composer audit / osv-scanner で監視・実稼働版で判定し即パッチ
P1本番キャッシュconfig:cache route:cache view:cache で確実な反映+高速化
P2セッション/Cookie 安全属性secure http_only same_site を設定。ログイン時にセッション再生成
P2アップロード検証種別・サイズ・保存先を検証。保存は public/ 外、実行権限なし
P2HTTPS/ヘッダ/レート制限HTTPS強制・HSTS等・ログイン/APIに throttle

1. 秘密と APP_KEY(P0)

Laravelは既定で .env をドキュメントルート外(プロジェクト直下)に置きます。事故は主に**「本来置かない場所に秘密を置く」**ことで起きます。

  • .env・DBダンプ・バックアップ・鍵ファイルを public/ に置かない。秘密はアプリルート外・権限600(所有者のみ)。
  • storage/storage/logs/ を公開しない(ログに秘密や個人情報が出ることがある)。.envリポジトリにコミットしない
  • APP_KEY は暗号化・署名付きURL・暗号化Cookie・セッションの土台。環境変数から注入し、漏洩したら速やかにローテーション(既存の暗号化データ/セッションは無効化される点に注意)。

秘密の置き場所の一般論は 公開ディレクトリに秘密を置かない、実際の全公開事例は .env全公開の事例 を参照。

2. 本番設定:DEBUG・環境・キャッシュ(P0)

1

APP_DEBUG=false / APP_ENV=production

本番ではデバッグを無効に。有効だと例外画面に環境変数・接続情報が露出し、故意のエラーで抜かれる。
2

設定をキャッシュして固定

php artisan config:cache(+route:cache view:cache)で確実に反映+高速化。注意:config:cache 後は config 配下の外で env() が null になるため、アプリ本体では config('...') 経由で参照する。
3

診断ツールを本番に露出しない

Telescope / Horizon / Debugbar などは本番で無効化またはアクセス制限。詳細エラー・スタックトレースを外部に出さない。

3. 認可:Broken Access Control(P1・最多の事故源)

実運用で最も多いのが「認証はあるが認可が無い」型です。ログインできること=その操作をしてよいこと、ではありません。

やりがち(危険)

  • 認可を書かず「ログイン=閲覧/更新可」
  • ルートモデル束縛で他人のIDでも取得できる
  • Model::create($request->all()) で全フィールド受け入れ
  • is_admin 等の権限フィールドをユーザー入力から代入

正しい

  • Policy / Gateauthorize()canミドルウェアで所有者/権限を毎回スコープ
  • 取得も where('user_id', $me) 等で所有者に限定
  • $request->validated()(FormRequest)で受け入れを限定
  • $fillable を明示し Mass Assignment を遮断

用語の詳細は IDORとは。取得・更新・削除のすべての経路で所有者チェックを通すのが要点です。

4. インジェクションと出力

Laravelの Eloquent/クエリビルダはプレースホルダで値をバインドし、Blade は既定で出力をエスケープします。この安全機構を自分で外さないのが基本です。

  • SQLwhereRawDB::raw文字列連結でユーザー入力を混ぜない。生SQLが要る場面でもバインドパラメータを使う(→ SQLインジェクションとは)。
  • XSS:Blade の {{ }} はエスケープ、{!! !!}生出力。ユーザー入力を {!! !!} に渡さない。どうしてもHTMLを出すならサニタイズ後に限定(→ XSSとは)。
  • 検証:入力は FormRequest / validate() で型・範囲・許可値を検証してから使う。

5. セッション・CSRF・Cookie(P2)

  • CSRF:web ミドルウェアの CSRF 保護を全体無効化しない。フォームに @csrf、SPAは適切なトークン運用(→ CSRFとは)。
  • Cookie/セッションconfig/session.phpsecure(HTTPS)・http_onlysame_site を設定。ログイン時にセッションを再生成してセッション固定を防ぐ(Laravelの認証は再生成する)。
  • ブルートフォース:ログインに throttle/認証試行制限をかける。

6. ファイルアップロードと公開ファイル(P2)

  • アップロードは種別(mime)・拡張子・サイズを検証し、クライアント提供のファイル名を信用しない
  • 保存先は public/storage/ 等)にし、実行権限を与えない。公開が必要なものだけ配信経路を用意する。
  • 連番の直リンクで他人のファイルを取得されないよう、配信にも認可を通す。

7. HTTPS・セキュリティヘッダ・レート制限(P2)

  • HTTPS強制URL::forceScheme('https') 等)+ HSTS。ロードバランサ配下では TrustProxies で正しいスキームを認識させる。
  • セキュリティヘッダ(X-Content-Type-Options 等・CSPはアセット構成に合わせて設計)。自サイトの状態は セキュリティヘッダ診断 で確認できる。
  • レート制限:ログイン・API・パスワードリセットに throttle を適用。

8. 依存とバージョン(P1)

  • Composer依存のCVEcomposer audit や osv-scanner で監視し、実稼働版で判定して即パッチ(→ 依存のCVE監視CVE対応の実務)。
  • Laravel本体とPHPをサポート対象バージョンに保つ。EOL版を放置しない(直らない穴が積み上がる)。

検証:自分のLaravelは固められているか

作ったら終わりでなく、点検して初めて完了です。以下は自分のサイト/環境に対する防御的な自己チェックです。

1

秘密がURLで取れないか

自分のドメインで /.env/storage/logs/laravel.log にアクセスして404になることを確認(取得できたら即対処+鍵ローテーション)。
2

本番でデバッグが露出していないか

わざと存在しないURL等でエラーを起こし、汎用エラーページが出る(環境変数やスタックトレースが出ない)ことを確認。
3

認可が効いているか

テスト環境で、他ユーザーのリソースIDを指定して拒否されることを確認(取得・更新・削除の各経路)。
4

Cookie/セッションと依存

セッションCookieに Secure/HttpOnly/SameSite が付くか確認。composer auditクリーンか確認。

当サイトの視点:堅い既定でも『認可と依存』は自分の責任

Laravelは良い既定を多く持ちますが、「誰が・何を・してよいか」という認可依存の鮮度だけは、アプリ固有・運用固有なのでフレームワークが自動で守れません。当サイトが繰り返し見る事故も、凝った攻撃より「認証はあるのに所有者チェックが無い」「本番でデバッグが開いていた」「秘密が露出していた」という設定・運用の型が中心です。だから守りの重心は、上の表を上から潰し、取得・更新のたびに所有者でスコープし、依存をCVE監視するという地味な徹底にあります。

次に読む

よくある質問

QLaravelで最初にやるべきセキュリティ対策は何ですか?
A

優先度P0の3つです。(1)本番で APP_DEBUG=false を確実にし、設定をキャッシュ(config:cache)して固定する、(2).env と秘密ファイルを公開ディレクトリ(public/)の外に置き権限を絞る、(3)APP_KEY を安全に管理する(暗号化・署名Cookie・セッションの土台なので漏洩はローテーション)。この3つは他の対策の前提になります。次に認可(Policy/Gate)と依存(Composer)のCVE監視へ進みます。

QAPP_DEBUG=true のまま本番に出すと何が危険ですか?
A

デバッグが有効だと、例外画面にスタックトレースだけでなく設定値・環境変数・接続情報などの内部が表示され得ます。攻撃者はわざと例外を起こして情報を引き出せます。本番では APP_DEBUG=false・APP_ENV=production を設定し、config:cache で確実に反映してください。あわせて Telescope / Debugbar など診断ツールを本番で公開しないこと。

Qconfig:cache を使うと env() が null になるのはなぜですか?
A

config:cache は設定を1ファイルにコンパイルして高速化しますが、その後は config ファイルの外で env() を呼ぶと null が返ります(キャッシュ時点の .env しか読まれないため)。対策は、env() は config/ 配下でのみ使い、アプリ本体では config('...') 経由で参照することです。本番では config/route/view をキャッシュするのが基本で、設定の確実な反映と高速化を両立できます。

Q『ログインしていれば見られる』を防ぐには?
A

認証(ログイン)と認可(その操作の可否)は別物です。Laravelでは Policy / Gate を実装し、コントローラで authorize() や can ミドルウェアを使って、取得・更新・削除のたびに所有者や権限をスコープします。あわせて Mass Assignment を $fillable の明示で制御し、$request->all() の丸ごと代入を避けます。これがないと、URLのIDを差し替えるだけで他人のデータに到達します(IDOR)。

Q依存パッケージ(Composer)の脆弱性はどう管理しますか?
A

composer audit や osv-scanner で既知CVEを機械監視し、『実稼働版』で判定して素早くパッチします(composer.json の宣言でなく、実際に入っている版で判断)。加えて Laravel 本体と PHP をサポート対象のバージョンに保ち、EOL版を放置しないこと。依存の鮮度は、凝った攻撃より事故を分ける現実的な要因です。