mcpField
L
laravel-owasp-security

laravel-owasp-security

github.com/asyrafhussinセキュリティ951.0k 回インストール9 週間前に更新
リポジトリ

laravel-owasp-security について

Laravel 13 アプリ向けのセキュリティ監査・コーディングガイドのスキルです。コードベースを OWASP Top 10 に照らして確認し、React + Inertia.js が検出された場合は追加チェックも行います。

主な機能

  1. 01OWASP Top 10 のコード監査
  2. 02React + Inertia.js のセキュリティ確認
  3. 03ファイルや機能単位の監査範囲指定
  4. 04問題箇所と修正案の提示
  5. 05Laravel の安全なコーディング規則

活用シーン

  1. 01リリース前の Laravel アプリ監査
  2. 02特定のコントローラーや機能の確認
  3. 03認証・決済・アップロード機能の開発
  4. 04Inertia ページのデータ露出確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/asyrafhussin/agent-skills --skill laravel-owasp-security

インストール後、Claude Code で/laravel-owasp-securityを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

AGENTS.md
metadata.json
README.md
rules/
_sections.md
_template.md
sec-authentication-rate-limiting.md
sec-broken-access-control.md
sec-cryptographic-failures.md
sec-csrf-protection.md
sec-inertia-data-exposure.md
sec-injection-prevention.md
sec-security-misconfiguration.md
sec-xss-react-inertia.md

詳細

Laravel OWASP セキュリティ

Laravel 13 + React/Inertia.js アプリケーション向けの、セキュリティ監査とセキュアコーディングの両方に使えるスキルです。コードベース全体に対して OWASP Top 10 の監査を実行するか、機能の構築時にセキュアコーディングのリファレンスとして使用します。

監査方法

ステップ 1:スタックを検出する

次の項目を確認し、プロジェクトで React + Inertia.js が使用されているか調べます。

  • app/Http/Middleware/HandleInertiaRequests.php が存在する
  • resources/js/ に .tsx または .jsx ファイルが含まれている
  • composer.json に inertiajs/inertia-laravel が含まれている
  • package.json に @inertiajs/react が含まれている

検出された場合、レポートの先頭に次のように記載します。

"React + Inertia.js が検出されました — Laravel OWASP チェックリストと React/Inertia セキュリティチェックの両方を適用します。"

検出されなかった場合、次のように記載します。

"React/Inertia.js は検出されませんでした — Laravel OWASP チェックリストのみを適用します。"

ステップ 2:対象範囲を決定する
  • 引数が指定されている場合($ARGUMENTS):指定されたファイルまたは機能のみを確認します
  • 引数が指定されていない場合:コードベース全体を確認します
ステップ 3:チェックリストを実行する

以下のすべての項目を確認します。それぞれについて、次のいずれかを出力します。

  • PASS — 検証した内容を簡潔に確認します
  • FAIL — 正確な file:line、脆弱性の説明(ファイル内のコード、値、API キー、トークン、または .env の内容を再掲しないでください)、および修正の推奨事項
  • N/A — このプロジェクトに該当しない場合

OWASP Top 10 チェックリスト

1. アクセス制御の不備(A01:2021)
  • すべてのルートグループがロール別のミドルウェア(auth、role:admin など)で保護されている
  • リソースクエリが認証済みユーザーに限定されている — ->where('user_id', auth()->id())
  • 所有権チェックのない直接的なオブジェクト参照がない
  • リソースへのアクセス認可に Gates と Policies が使用されている
  • フロントエンドのロールチェックがサーバー側でも適用されている — React UI のチェックだけに決して依存しない
2. 暗号化の失敗(A02:2021)
  • パスワードが Hash::make() または 'hashed' Eloquent キャストでハッシュ化されている — 平文で保存しない
  • パスワードのハッシュ化に MD5 または SHA1 が使用されていない
  • 機密フィールド(API キー、シークレット)が Crypt::encryptString() または 'encrypted' Eloquent キャストで暗号化されている
  • APP_KEY が長く、ランダムで、環境ごとに固有である
  • 機密性の高い単発操作(パスワードリセット、メール認証)に署名付き URL(URL::signedRoute())が使用されている
3. インジェクション(A03:2021)

SQL と一括代入:

  • whereRaw()、selectRaw()、orderByRaw() に文字列連結がない — ? バインディングを使用する
  • ホワイトリストなしに、ユーザー入力からカラム名を決定していない
  • $request->all() を create()、fill()、または update() に直接渡していない
  • 未検証のユーザー入力を使って forceFill() または forceCreate() を呼び出していない
  • モデルで $fillable が明示的に定義されている — $guarded = [] を使用していない
  • コントローラーで一括操作に $request->validated() を使用している

XSS — Blade と React:

  • 信頼できないデータを含む Blade テンプレートで {!! $userInput !!} を使用していない
  • ユーザーが指定した Blade 出力にはすべて {{ }} を使用している
  • 事前に DOMPurify.sanitize() を適用せずに、React で dangerouslySetInnerHTML を使用していない
  • 未検証のユーザー入力から href および src 属性を設定していない
  • ユーザーが制御できる文字列を使って eval()、new Function()、または setTimeout(string) を使用していない
  • 外部 CDN のスクリプトで Subresource Integrity(integrity="sha384-...")を使用している
4. 安全でない設計(A04:2021)
  • ビジネスロジックがサーバー側で強制されている — 価格、合計額、割引をクライアント入力から信頼していない
  • 機密性の高い操作に追加の確認(アカウント削除時のパスワード再入力など)を求めている
  • アイテムごとの認可チェックを行わない一括操作エンドポイントがない
  • 管理者限定機能が独立したミドルウェアで保護されている — UI で非表示にするだけではない
  • 支払い金額と登録状態がサーバー側で計算されており、フォーム入力として渡されていない
5. セキュリティ設定の不備(A05:2021)
  • 本番環境で APP_DEBUG=false に設定されている
  • .env が .gitignore に含まれており、コミットされていない
  • 本番環境のデータベースでは、root/admin ではなく権限を制限したユーザーを使用している
  • storage/ と bootstrap/cache/ の権限が適切に設定されている(全ユーザーが書き込み可能な状態ではない)
  • APP_KEY が設定されており、環境ごとに一意である
  • 認証が必要な API ルートで、CORS の allowed_origins が ['*'] になっていない
6. 脆弱で古いコンポーネント(A06:2021)
  • composer audit で既知の CVE が検出されない
  • npm audit で既知の CVE が検出されない
  • Laravel フレームワークがサポート対象のバージョンである
7. 識別および認証の失敗(A07:2021)

認証:

  • 独自実装の認証ではなく、Laravel Breeze、Fortify、または Jetstream を使用している
  • パスワードが bcrypt または argon2(Laravel のデフォルト)でハッシュ化されている
  • ログインルートにレート制限が設定されている — throttle ミドルウェア、または LoginRequest の RateLimiter を使用
  • パスワードリセットとメール認証のルートにレート制限が設定されている
  • 決済ルートと機密性の高い操作ルートに適切なレート制限が設定されている
  • ログイン成功後に session()->regenerate() が呼び出されている

Cookie とセッション:

  • config/session.php で http_only = true に設定されている
  • config/session.php で same_site = lax または strict に設定されている
  • config/session.php で secure = true または null(HTTPS の場合は自動設定)に設定されている
  • lifetime が妥当な値に設定されている(ほとんどのアプリでは 15〜30 分を推奨)
  • サブドメインが必要な場合を除き、domain = null に設定されている
  • EncryptCookies ミドルウェアが web グループに含まれている
8. ソフトウェアとデータの完全性に関する失敗(A08:2021)

CSRF:

  • VerifyCsrfToken ミドルウェアが web グループで有効になっている
  • CSRF の対象外は、ステートレスなルート(Webhook、外部コールバック)のみである
  • Inertia を使用しないすべての POST フォームで @csrf ディレクティブを使用している
  • validateCsrfTokens(except: [...]) で対象外にしているルートに正当な理由がある

デシリアライズ:

  • unserialize($request->input(...)) を使用していない
  • eval($request->input(...)) を使用していない
  • extract($request->all()) を使用していない
9. セキュリティログ記録と監視の失敗(A09:2021)
  • ログイン失敗が IP アドレスと識別子とともに記録されている
  • 決済の失敗と例外が記録されている
  • ログエントリにパスワードやシークレットがそのまま含まれていない
  • 監視が導入されている(Laravel Telescope、Sentry など)
10. サーバーサイドリクエストフォージェリ — SSRF(A10:2021)
  • URL を検証せずに Http::get($request->input('url')) を使用していない
  • ユーザーが指定した URL を許可リストまたはスキームチェックで検証している
  • ユーザーが指定した URL から内部ネットワークアドレスへのアクセスをブロックしている

追加のチェック項目

OWASP Top 10 には含まれませんが、Laravel アプリケーションでは重要です。

コマンドインジェクションと危険な関数
  • ユーザー入力を使って exec()、shell_exec()、system()、passthru() を呼び出していない
  • オープンリダイレクトがない — URL を検証せずに redirect($request->input('url')) を使用していない
  • ファイルアップロードで mimes: と max: を検証している — ファイル名をユーザー入力から直接生成していない
セキュリティヘッダー
  • Content-Security-Policy が設定されている — 可能であれば nonce(Vite::useCspNonce())を使用
  • X-Frame-Options が設定されている
  • X-Content-Type-Options が設定されている
  • HTTPS 用に Strict-Transport-Security が設定されている
  • Referrer-Policy が設定されている
  • Permissions-Policy が設定されている

React + Inertia.js のチェック項目

ステップ 1 で React + Inertia.js が検出された場合にのみ実行してください。

R1. React コンポーネントの XSS
  • 先に DOMPurify.sanitize() を実行せずに dangerouslySetInnerHTML={{ __html: userInput }} を使用していない
  • href および src 属性に未検証のユーザー入力を設定していない — javascript: URL はスクリプトを実行します
  • ユーザーが制御する文字列を使って eval()、new Function()、または setTimeout(string) を呼び出していない
  • ユーザー入力のリンクでスキームを検証している(https:// または http:// のみ)
R2. Inertia.js のデータ漏えい(重大)
  • HandleInertiaRequests::share() でパスワード、トークン、内部専用フラグが公開されない
  • コントローラーでは ->only([...]) または API リソースを使用し、モデルの toArray() をそのまま使用しない
  • すべての Inertia props は公開情報として扱う — 初回読み込み時に data-page HTML 属性で表示されます
  • 決済のシークレットキーや管理者専用の認証情報を Inertia props として渡さない
  • 機密データを含むページでは Inertia v2 の履歴暗号化を有効にする
R3. Inertia.js の CSRF
  • Inertia の X-XSRF-TOKEN ヘッダーを無効にしない
  • Inertia のルーターを経由しないカスタムの fetch または axios 呼び出しでは、CSRF トークンを手動で含める
  • CSRF の除外対象とするのは、Webhook/コールバックルートのみ
R4. React での認証状態
  • Inertia prop の auth.user から、パスワードハッシュ、remember トークン、2FA シークレットを除外する
  • ロール/権限のチェックはサーバー側で適用する — React 側のチェックは UI 専用です
  • auth.user には UI が実際に必要とするフィールドのみを含める
R5. ブラウザー内の機密データ
  • React コンポーネントや TypeScript ファイルに API キーやシークレットをハードコードしない
  • localStorage や sessionStorage に機密データを保存しない — HttpOnly Cookie を使用する
  • VITE_* 環境変数にシークレットを含めない — 設計上、公開されています
R6. 依存関係のセキュリティ
  • npm audit を実行し、React または Inertia パッケージに高または重大な CVE がないことを確認する
  • サポート対象のバージョンの React を使用する
  • サードパーティのコンポーネントライブラリに既知の CVE がないか確認する

出力形式

監査レポートは次の形式で構成してください。

## Laravel OWASP Security Audit Report

> React + Inertia.js detected — Laravel OWASP checklist AND React/Inertia security checks will both be applied.

### 1. Broken Access Control (A01:2021)
- **PASS** `app/Http/Middleware/RoleMiddleware.php` — role middleware applied to all route groups
- **FAIL** `app/Http/Controllers/PaymentController.php:42` — Payment model fetched without ownership check (direct object reference exposure). Fix: scope the query to the authenticated user.

[Continue for all 10 OWASP checks + Additional Checks + R1–R6 React/Inertia checks]

---

## Summary

### Critical Issues (fix immediately)
1. ...

### Warnings (fix soon)
1. ...

### Passed
X checks passed.

### Recommended Commands
composer audit
npm audit

ガイダンスを参照するタイミング

次の場合はルールファイルを参照してください。

  • 認証またはパスワード処理を実装するとき
  • 決済または Webhook 連携を構築するとき
  • ファイルのアップロードまたはダウンロードのロジックを記述するとき
  • 管理者向けまたはロールベースのアクセス制御を設計するとき
  • ユーザー入力を受け取る API エンドポイントを構築するとき
  • React コンポーネントで dangerouslySetInnerHTML を使用するとき
  • Laravel コントローラーから Inertia props にデータを渡すとき

優先度別のルールカテゴリ

優先度カテゴリ影響度ルールファイル
1アクセス制御の不備CRITICALsec-broken-access-control
2暗号化の失敗CRITICALsec-cryptographic-failures
3インジェクションの防止CRITICALsec-injection-prevention
4XSS と React/InertiaHIGHsec-xss-react-inertia
5CSRF の保護HIGHsec-csrf-protection
6セキュリティ設定の不備HIGHsec-security-misconfiguration
7認証とレート制限HIGHsec-authentication-rate-limiting
8Inertia のデータ漏えいHIGHsec-inertia-data-exposure

クイックリファレンス

1. アクセス制御の不備(CRITICAL)
  • sec-broken-access-control — ミドルウェア、所有権チェック、ポリシー、スコープ付きクエリ
2. 暗号化の失敗(CRITICAL)
  • sec-cryptographic-failures — パスワードのハッシュ化、暗号化キャスト、署名付き URL
3. インジェクションの防止(CRITICAL)
  • sec-injection-prevention — SQL インジェクション、一括代入、raw クエリのバインディング
4. XSS と React/Inertia(HIGH)
  • sec-xss-react-inertia — dangerouslySetInnerHTML、DOMPurify、href/src の検証
5. CSRF の保護(HIGH)
  • sec-csrf-protection — VerifyCsrfToken、Webhook の除外、Inertia の CSRF
6. セキュリティ設定の不備(HIGH)
  • sec-security-misconfiguration — APP_DEBUG、APP_KEY、セキュリティヘッダー、CORS
7. 認証とレート制限(HIGH)
  • sec-authentication-rate-limiting — スロットリング、セッションの再生成、ブルートフォース攻撃の防止
8. Inertia のデータ漏えい(HIGH)
  • sec-inertia-data-exposure — data-page 属性の露出、シークレットを含む props、API リソース

使用方法

詳しい説明とコード例については、個々のルールファイルを読んでください。

rules/sec-broken-access-control.md
rules/sec-cryptographic-failures.md
rules/sec-injection-prevention.md
rules/sec-xss-react-inertia.md
rules/sec-csrf-protection.md
rules/sec-security-misconfiguration.md
rules/sec-authentication-rate-limiting.md
rules/sec-inertia-data-exposure.md

各ルールファイルには次の内容が含まれています。

  • メタデータ(タイトル、影響度、タグ)を含む YAML frontmatter
  • Laravel/React のコンテキストで重要となる理由
  • 説明付きの誤ったコード例
  • 修正を示す正しいコード例
  • Laravel 13 および PHP 8.3+ 固有のコンテキスト

コンパイル済みドキュメント全体

すべてのルールを展開した完全なガイドについては、AGENTS.md をご覧ください。

コメント