mcpField
S
security-review

security-review

github.com/shiplightaiセキュリティ2409 回インストール16 週間前に更新
リポジトリ

security-review について

security-review は、リリース前の確認、大きな変更の再審査、監査準備に使うアプリケーションセキュリティ評価手順です。コードベース分析とブラウザテストを組み合わせ、証拠付きの指摘、修正案、YAML 回帰テストを作成します。

主な機能

  1. 01攻撃対象領域とデータフローの整理
  2. 02HTTP セキュリティヘッダーの確認
  3. 03認証・セッション・アクセス制御のテスト
  4. 04インジェクションとクライアント側セキュリティの確認
  5. 05依存関係とサプライチェーンのレビュー
  6. 06レポート、修正案、YAML テスト

活用シーン

  1. 01Web アプリのリリース前セキュリティ確認
  2. 02認証または認可の変更のレビュー
  3. 03セキュリティ監査向けの証拠と指摘の整理
  4. 04インシデント後に類似の弱点を調査

インストール

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

$npx skills add https://github.com/shiplightai/agent-skills --skill security-review

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

詳細

セキュリティレビュー

業界標準に照らしてアプリケーションのセキュリティ態勢を評価し、ブラウザーを使ったペネトレーションテストで調査結果を検証します。このレビューでは、静的解析ツールでは見つけられない攻撃対象領域、つまり実行時の動作、ヘッダー設定、認証フロー、クライアント側の脆弱性を調べます。

使用するタイミング

次の場合は /security-review を使用します。

  • 新しいアプリケーションや機能をリリースする前
  • 認証または認可に関する変更を加えた後
  • 機密データ(ユーザー認証情報、決済情報、PII)を扱う場合
  • セキュリティ監査の準備をする場合
  • セキュリティインシデントの後、同様の問題がないか確認する場合
  • サードパーティ連携をレビューする場合

参照する標準

  • OWASP Top 10 (2021) — Web アプリケーションの主なセキュリティリスク
  • OWASP ASVS v4.0 — アプリケーションセキュリティ検証標準
  • OWASP Session Management Cheat Sheet
  • NIST 800-63B — デジタルアイデンティティガイドライン(認証)
  • CWE/SANS Top 25 — 最も危険なソフトウェアの弱点
  • Mozilla Observatory — HTTP セキュリティヘッダーのベストプラクティス

フェーズの概要

Phase 1: EDUCATE   → Security context and what we check
Phase 2: SCOPE     → Identify attack surface, auth mechanisms, data flows
Phase 3: ANALYZE   → Automated checks + browser-based penetration testing
Phase 4: REPORT    → Findings with evidence, CVE references, confidence scores
Phase 5: REMEDIATE → Fix guidance + YAML regression tests

フェーズ 1:理解を深める

重要な理由: データ侵害による平均損失額は 445 万ドルです(IBM 2023)。Web アプリケーションの 83% に、少なくとも 1 つの重大な脆弱性があります。多くのセキュリティ上の問題は、設定ミスのあるヘッダー、安全でないトークン保存、アクセス制御の不備など、実行時にしか検出できません。これらを検出できるのが、まさにブラウザーを使ったテストです。

このレビューでは、ブラウザーを使った検証により、客観的なセキュリティ基準に照らしてアプリを確認します。検出結果にはすべて、具体的な標準(OWASP、CWE、NIST)を記載します。


フェーズ 2:対象範囲

コンテキストを収集する
  1. コードベースから自動検出する:

    • 認証方式(JWT、セッション、OAuth、API キー)
    • 使用中のフレームワークのセキュリティ機能(CSRF トークン、CORS 設定、CSP)
    • 既知の脆弱性がある依存関係(npm audit / pip audit)
    • API ルートとエンドポイント
    • 環境変数の取り扱い
    • ファイルアップロード機能
    • サードパーティスクリプトと CDN の使用状況
  2. ユーザーに一度に 1 つずつ質問する:

    • 対象 URL:アプリはどこで実行されていますか?
    • 認証方式:ユーザーはどのようにログインしますか?(自動検出した内容を確認)
    • テスト用認証情報:テストに使用できるアカウントはありますか?(認証が必要なテストで使用します)
    • 機密データ:アプリはどのような機密データを扱いますか?(PII、決済情報、健康記録)
    • 既知の懸念事項:特に心配している領域はありますか?(任意)
  3. 攻撃対象領域をマッピングする:

    • すべてのユーザー入力箇所(フォーム、URL パラメーター、ファイルアップロード、WebSocket メッセージ)を列挙する
    • 認証要件を含むすべての API エンドポイントを列挙する
    • すべてのサードパーティ連携を列挙する
    • データフローを特定する:機密データはどこから入り、どこで処理・保存され、どこから出ていきますか?

フェーズ 3:分析する

record_evidence: true を指定して new_session でブラウザーセッションを開き、該当するすべてのチェックカテゴリを実行します。

カテゴリー A:HTTP セキュリティヘッダー(HDR)
チェック IDチェック項目標準方法
HDR-01Content-Security-Policy ヘッダーが存在し、制限的に設定されているOWASP A05レスポンスヘッダーを確認
HDR-02Strict-Transport-Security(HSTS)の max-age が長く設定されているOWASP Transportヘッダーの有無と値を確認
HDR-03X-Content-Type-Options: nosniffMozilla Observatoryヘッダーを確認
HDR-04X-Frame-Options または CSP frame-ancestors が設定されているOWASP Clickjackingヘッダーを確認
HDR-05Referrer-Policy が適切に設定されているプライバシー/セキュリティヘッダー値を確認
HDR-06Permissions-Policy により機密性の高い API が制限されているブラウザーセキュリティカメラ、マイク、位置情報のポリシーを確認
HDR-07Server/X-Powered-By によるバージョン情報の開示がない情報漏えいヘッダーにバージョン文字列が含まれていないか確認
HDR-08機密性の高いページに Cache-Control が設定されているOWASP Session認証済みコンテンツに no-store が設定されているか確認
HDR-09CORS の許可範囲が広すぎないOWASP A05Access-Control-Allow-Origin を確認
HDR-10混在コンテンツ(HTTPS ページ上の HTTP リソース)がない通信セキュリティすべてのリソース URL を確認

ブラウザーでの検証: act を使って JavaScript から document.querySelector('meta[http-equiv]') を調べ、同一オリジンのリクエストを使ってレスポンスヘッダーを取得します。get_browser_console_logs を使い、混在コンテンツの警告がないか確認します。

カテゴリー B:認証とセッション管理(AUTH)
チェック IDチェック項目標準方法
AUTH-01トークンが localStorage に保存されていないOWASP ASVS 3.3.2localStorage/sessionStorage にトークンがないか確認
AUTH-02セッション Cookie に HttpOnly フラグが設定されているOWASP SessionSet-Cookie ヘッダーを調べる
AUTH-03セッション Cookie に Secure フラグが設定されているOWASP SessionSet-Cookie ヘッダーを調べる
AUTH-04セッション Cookie に SameSite 属性が設定されているOWASP CSRFSet-Cookie ヘッダーを調べる
AUTH-05アイドルタイムアウト後にセッションが失効するOWASP ASVS 3.3.1待機してセッションが無効化されることを確認
AUTH-06ログアウトによりサーバー側のセッションが無効化されるOWASP ASVS 3.3.1ログアウトし、古いトークンを再送してレスポンスを確認
AUTH-07パスワードリセットトークンが一度しか使えないOWASP Authリセットリンクを 2 回使い、2 回目が失敗することを確認
AUTH-08URL パラメーターに認証情報が含まれていないOWASP TransportURL にトークンやパスワードが含まれていないか確認
AUTH-09ログイン時にブルートフォース攻撃への保護があるOWASP Authログインに複数回失敗し、ロックアウト/レート制限を確認
AUTH-10状態を変更するリクエストに CSRF 保護があるOWASP A01CSRF トークンなしでフォームを送信
AUTH-11JWT の署名が検証される(該当する場合)OWASP Auth改変した JWT を送信し、拒否されることを確認
AUTH-12OAuth の state パラメーターが使用される(該当する場合)OWASP AuthOAuth フローに state パラメーターがあるか確認

ブラウザーでの検証: act でログインし、JavaScript(document.cookie — HttpOnly Cookie が表示されないのは正しい動作です)を使って Cookie を調べます。localStorage を確認します。ログアウト後にリクエストを再送します。ブルートフォース攻撃を試します(誤ったパスワードを 5 回入力)。JWT トークンを改変してテストします。

カテゴリ C:入力検証とインジェクション(INJ)
チェック IDチェック項目標準方法
INJ-01XSS:ページに反映される入力OWASP A03 / CWE-79すべての入力欄に <script>alert(1)</script> を送信し、表示されるか確認します
INJ-02XSS:データベースに保存される入力OWASP A03 / CWE-79フォームからスクリプトを送信し、後続のページ読み込み時に表示されるか確認します
INJ-03フォーム入力での SQL インジェクションOWASP A03 / CWE-89' OR '1'='1 パターンを送信し、エラーが発生するか確認します
INJ-04URL パラメーター経由のオープンリダイレクトCWE-601外部 URL を指定したリダイレクトパラメーターをテストします
INJ-05ファイル操作でのパストラバーサルCWE-22ファイル関連のパラメーターに ../../etc/passwd を指定してテストします
INJ-06入力フィールドでのコマンドインジェクションCWE-78入力がシェルに渡される可能性のある箇所で、; ls または `
INJ-07ユーザーコンテンツでの HTML インジェクションCWE-79HTML タグを送信し、表示されるか確認します
INJ-08URL スキームの検証(javascript:)CWE-79URL 入力欄に javascript:alert(1) を指定してテストします
INJ-09ファイルアップロードの検証OWASP A04拡張子が不正なファイル、サイズが大きすぎるファイル、実行可能なコンテンツを含むファイルをアップロードします
INJ-10API 入力の検証OWASP A03API エンドポイントに不正な JSON、必須フィールドの欠落、誤った型の値を送信します

ブラウザーでの検証: act を使用して、フォームフィールドにテスト用ペイロードを入力します。送信後のページ状態を記録します。スクリプトの実行、エラーメッセージ、予期しない動作がないか確認します。インジェクションの経路を示す JavaScript エラーを確認するには、get_browser_console_logs を使用します。

重要: これらは検出のみを目的とした、非破壊のテスト用ペイロードです。実際の悪用は試みないでください。アラートを使った XSS テストでは、無害な alert(1) を使用します。

カテゴリ D:アクセス制御(AC)
チェック IDチェック項目標準方法
AC-01認証がない場合、認証が必要なページは 401/403 を返すOWASP A01認証せずに保護された URL にアクセスします
AC-02IDOR(安全でない直接オブジェクト参照)がないOWASP A01 / CWE-639URL 内のリソース ID を変更し、不正なアクセスが可能か確認します
AC-03API エンドポイントで認可が適用されるOWASP A01誤った認証情報または認証情報なしで API エンドポイントを呼び出します
AC-04管理者用ページに一般ユーザーがアクセスできないOWASP A01一般ユーザーのセッションで管理者用ルートに移動します
AC-05クライアント側のソースに機密データが含まれていない情報漏えいJavaScript バンドルに API キーやシークレットが含まれていないか確認します
AC-06ディレクトリー一覧が無効になっている情報漏えいディレクトリー URL(例:/api/、/static/)にアクセスします
AC-07デバッグ用エンドポイントが本番環境で公開されていないOWASP A05一般的なデバッグ用パス(/debug、/trace、/graphql playground)を確認します
AC-08エラーメッセージから内部の詳細が漏えいしないOWASP A05エラーを発生させ、スタックトレースやデータベースの詳細が表示されないか確認します

ブラウザーでの検証: 認証なしで保護されたページに移動します。他のユーザーに属するリソースへのアクセスを試みます。JavaScript を使用する act でスクリプトの内容をスキャンし、JavaScript ソースにハードコードされたシークレットがないか確認します。

カテゴリ E:クライアント側のセキュリティ(CLI)
チェック IDチェック項目基準方法
CLI-01クライアント側ストレージに機密データがないOWASP StoragelocalStorage、sessionStorage、IndexedDB を検査
CLI-02CDN リソースにサブリソース完全性(SRI)が設定されているサプライチェーン外部スクリプト/スタイルの integrity 属性を確認
CLI-03サードパーティスクリプトの一覧サプライチェーンすべての外部スクリプトのソースを一覧表示
CLI-04ユーザー入力に対して eval() や innerHTML を使用していないCWE-79JavaScript をスキャンし、危険なパターンを検出
CLI-05サービスワーカーのスコープが制限されているクライアントセキュリティSW の登録スコープを確認
CLI-06WebSocket 接続で WSS を使用しているトランスポートWS 接続 URL を確認
CLI-07コンソールログに機密データがない情報漏えいget_browser_console_logs の出力を確認
CLI-08クリックジャッキング対策が機能しているOWASP Clickjackingページを iframe に埋め込んでテスト

ブラウザーでの検証: act を使って JavaScript から localStorage のキーを列挙し、SRI が設定されているかスクリプトタグを確認し、外部ドメインへのすべてのネットワークリクエストを一覧表示します。漏えいデータがないか、get_browser_console_logs を使って確認します。

カテゴリ F:依存関係とサプライチェーン(DEP)
チェック IDチェック項目基準方法
DEP-01既知の脆弱性を持つ依存関係がないOWASP A06 / CWE-1035npm audit / pip audit を実行
DEP-02ロックファイルが存在し、コミットされているサプライチェーンpackage-lock.json / yarn.lock / pnpm-lock.yaml があるか確認
DEP-03不要な依存関係がない攻撃対象領域未使用のパッケージがないか確認
DEP-04CDN リソースで SRI を使用しているサプライチェーンintegrity 属性を確認(CLI-02 と同じ)
DEP-05依存関係にタイポスクワッティングのリスクがないサプライチェーンパッケージ名を既知のパッケージと照合

検証: 依存関係の監査コマンドを実行します。フェーズ 2 のコードベーススキャン結果と相互参照します。


フェーズ 4:レポート

以下に保存する、構造化されたレポートを生成します:shiplight/reports/security-review-{date}.md

# Security Review Report
**Date:** {date}
**URL:** {url}
**Auth mechanism:** {type}
**Attack surface:** {summary}

## Overall Score: {X}/10 | Confidence: {X}%

## Score Breakdown
| Category | Score | Findings |
|----------|-------|----------|
| HTTP Headers (HDR) | 6/10 | 1 critical, 2 high |
| Auth & Sessions (AUTH) | 4/10 | 2 critical, 1 high |
| Input Validation (INJ) | 7/10 | 1 high, 2 medium |
| Access Control (AC) | 8/10 | 1 medium |
| Client-Side (CLI) | 5/10 | 1 critical, 1 high |
| Dependencies (DEP) | 9/10 | 1 low |

## Findings

### CRITICAL

#### AUTH-01: JWT stored in localStorage — XSS leads to full account takeover
- **Standard:** OWASP ASVS 3.3.2 / CWE-922
- **Finding:** Access token stored in `localStorage` under key `auth_token`, accessible to any XSS payload
- **Evidence:** [screenshot of Application > Storage showing JWT]
- **Attack scenario:** Any XSS vulnerability (even via third-party script) can exfiltrate all user tokens
- **CVSS estimate:** 8.1 (High)
- **Confidence:** 95%

...
確信度スコア
  • 90-100%:ブラウザーで悪用し、検証済み(例:XSS ペイロードの実行、権限のないアクセスを確認)
  • 70-89%:検査で強い証拠を確認(例:ヘッダーの欠落、セキュリティ設定が不適切な Cookie フラグを確認)
  • 50-69%:コードレベルの証拠はあるが、実行時に十分な検証ができていない
  • 50% 未満:報告しないでください。推測の域を出ません

フェーズ 5:修正

各検出事項について、以下を提示します。

1. 修正方法
#### AUTH-01: JWT stored in localStorage
**Risk:** Any XSS → full account takeover
**File:** src/lib/auth.ts:47
**Current:** `localStorage.setItem('auth_token', jwt)`
**Fix:** Move to HttpOnly cookie set by the server
- Server: `Set-Cookie: token=<jwt>; HttpOnly; Secure; SameSite=Strict; Path=/`
- Client: Remove all localStorage token operations
- API calls: Cookies sent automatically (remove Authorization header)
**Migration steps:**
1. Add cookie-setting endpoint on server
2. Update API middleware to read from cookie
3. Remove client-side token storage
4. Update CORS to allow credentials
2. YAML 回帰テスト
- name: auth-01-no-tokens-in-localstorage
  description: Verify authentication tokens are not stored in localStorage
  severity: critical
  standard: OWASP-ASVS-3.3.2
  steps:
    - URL: /login
    - intent: Enter test username
      action: fill
      locator: "getByLabel('Email')"
      value: "[email protected]"
    - intent: Enter test password
      action: fill
      locator: "getByLabel('Password')"
      value: "testpass123"
    - intent: Click login button
      action: click
      locator: "getByRole('button', { name: 'Sign in' })"
    - WAIT_UNTIL: User is logged in and dashboard is visible
      timeout_seconds: 15
    - description: Assert no auth tokens are stored in localStorage
      js: |
        const keys = Object.keys(localStorage);
        const tokenKeys = keys.filter(k =>
          /token|jwt|auth|session|access/i.test(k)
        );
        if (tokenKeys.length > 0) {
          throw new Error(
            `Auth tokens found in localStorage: ${tokenKeys.join(', ')}`
          );
        }
    - VERIFY: No authentication tokens are stored in browser localStorage

すべての YAML テストを shiplight/tests/security-review.test.yaml に保存します。


ペネトレーションテストの深度レベル

  • --quick:ヘッダー(HDR)+ Cookie フラグ(AUTH-02/03/04)+ localStorage の確認(AUTH-01)+依存関係の監査(DEP-01)。約 2 分。
  • デフォルト:すべてのカテゴリ、標準ペイロード。約 10 分。
  • --thorough:すべてのカテゴリ+拡張インジェクションペイロード+ IDOR の列挙+ブルートフォーステスト+サードパーティスクリプトの完全な分析。約 20~30 分。

ヒント

  • 常にテスト用の認証情報を使用し、本番環境の認証情報は使用しないでください
  • XSS テストペイロードは非破壊的(alert(1))で、ステージング環境で安全に使用できます
  • 認証済みのテストでは、ログイン後に save_storage_state でセッションを保存します
  • ブラウザーベースのレビューを行う前に npm audit を実行し、既知の CVE を早期に検出します
  • get_browser_console_logs を使用してください。多くのセキュリティ問題はコンソール警告を出力します
  • close_session でセッションを閉じ、証拠には generate_html_report を使用します

コメント