対象:Laravelを本番で運用している人。ここでは攻撃手順は扱わず、本番を固めるための実務リファレンス(優先度つきチェックリスト・危険な既定・領域別対策・自己検証)を示します。フレームワーク全体の考え方は フレームワーク別セキュリティの一覧 も参照。
優先度つきハードニング・チェックリスト
まずこの表を上から実施します。P0は他対策の前提、P1が最頻の事故源、P2は継続的な運用で守る項目です。
P0 ── 前提(まずこれ)
本番デバッグ無効 / 秘密を公開面の外+権限600 / APP_KEY 安全管理
P1 ── 最頻の事故源
認可(Policy/Gate) / Mass Assignment制御 / 依存CVE監視 / 本番キャッシュ
P2 ── 継続的な運用
セッション/CSRF/Cookie / アップロード検証 / HTTPS・ヘッダ・レート制限
| 優先 | 対策 | 具体(Laravel) |
|---|---|---|
| P0 | 本番デバッグ無効 | APP_DEBUG=false / APP_ENV=production を config:cache で固定。例外画面に内部を出さない |
| P0 | 秘密を公開面の外へ | .env・バックアップ・鍵は public/ 外。権限600。storage/logs も非公開 |
| P0 | APP_KEY を安全管理 | 暗号化・署名Cookie・セッションに使われる鍵。環境から注入・漏洩時ローテーション |
| P1 | 認可を明示 | Policy / Gate + authorize()・can ミドルウェアで所有者/権限スコープ |
| P1 | Mass 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/ 外、実行権限なし |
| P2 | HTTPS/ヘッダ/レート制限 | 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)
APP_DEBUG=false / APP_ENV=production
設定をキャッシュして固定
php artisan config:cache(+route:cache view:cache)で確実に反映+高速化。注意:config:cache 後は config 配下の外で env() が null になるため、アプリ本体では config('...') 経由で参照する。診断ツールを本番に露出しない
3. 認可:Broken Access Control(P1・最多の事故源)
実運用で最も多いのが「認証はあるが認可が無い」型です。ログインできること=その操作をしてよいこと、ではありません。
やりがち(危険)
- 認可を書かず「ログイン=閲覧/更新可」
- ルートモデル束縛で他人のIDでも取得できる
Model::create($request->all())で全フィールド受け入れis_admin等の権限フィールドをユーザー入力から代入
正しい
- Policy / Gate+
authorize()・canミドルウェアで所有者/権限を毎回スコープ - 取得も
where('user_id', $me)等で所有者に限定 $request->validated()(FormRequest)で受け入れを限定$fillableを明示し Mass Assignment を遮断
用語の詳細は IDORとは。取得・更新・削除のすべての経路で所有者チェックを通すのが要点です。
4. インジェクションと出力
Laravelの Eloquent/クエリビルダはプレースホルダで値をバインドし、Blade は既定で出力をエスケープします。この安全機構を自分で外さないのが基本です。
- SQL:
whereRaw・DB::rawに文字列連結でユーザー入力を混ぜない。生SQLが要る場面でもバインドパラメータを使う(→ SQLインジェクションとは)。 - XSS:Blade の
{{ }}はエスケープ、{!! !!}は生出力。ユーザー入力を{!! !!}に渡さない。どうしてもHTMLを出すならサニタイズ後に限定(→ XSSとは)。 - 検証:入力は FormRequest /
validate()で型・範囲・許可値を検証してから使う。
5. セッション・CSRF・Cookie(P2)
- CSRF:web ミドルウェアの CSRF 保護を全体無効化しない。フォームに
@csrf、SPAは適切なトークン運用(→ CSRFとは)。 - Cookie/セッション:
config/session.phpでsecure(HTTPS)・http_only・same_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依存のCVEを
composer auditや osv-scanner で監視し、実稼働版で判定して即パッチ(→ 依存のCVE監視 / CVE対応の実務)。 - Laravel本体とPHPをサポート対象バージョンに保つ。EOL版を放置しない(修正されない脆弱性が増えていく)。
検証:自分のLaravelは固められているか
作ったら終わりではありません。点検して初めて完了です。以下は自分のサイト/環境に対する防御的な自己チェックです。
秘密がURLで取れないか
/.env や /storage/logs/laravel.log にアクセスして404になることを確認(取得できたら即対処+鍵ローテーション)。本番でデバッグが露出していないか
認可が効いているか
Cookie/セッションと依存
composer audit がクリーンか確認。当サイトの視点:既定が安全寄りでも、認可と依存は自分の責任
Laravelは良い既定を多く持ちますが、「誰が・何を・してよいか」という認可と依存を最新に保つことだけは、アプリ固有・運用固有なのでフレームワークが自動で守れません。当サイトが繰り返し見る事故も、凝った攻撃より「認証はあるのに所有者チェックが無い」「本番でデバッグが開いていた」「秘密が露出していた」という設定・運用の型が中心です。だから重点は、上の表を上から順に実施し、取得・更新のたびに所有者で絞り込み、依存をCVE監視するという基本を徹底することです。
次に読む
- 一覧:フレームワーク別セキュリティ(一覧) / Next.jsのセキュリティ対策
- 秘密:公開ディレクトリに秘密を置かない / 事例:.env全公開の事例
- 認可・実務:IDORとは / 脆弱性(CVE)対応の実務 / 依存のCVE監視
- 用語:SQLインジェクション / XSS / CSRF
出典と確認範囲
以下は上記の設定・影響範囲・対策を確認するための原典です。2026年10月23日に参照先を確認しました。各版・構成の条件は原典で確認してください。チェックリストの優先順位や教訓は当サイトの整理であり、記事全体の再検証や安全性の保証を意味しません。