# Sec Runtime Scan

> ステージング環境にデプロイ済みのサーバーに対してランタイム検証を実行する。HTTPヘッダー・動的プローブ・認証テストに特化。手動呼び出し専用: /sec-runtime-scan [環境名]

- Skill: `studiogadget/sec-runtime-scan` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add studiogadget/sec-runtime-scan`
- Raw SKILL.md: https://api.skillmd.com/api/skills/studiogadget/sec-runtime-scan/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT (see LICENSE.txt)
- Author: studiogadget (https://skillmd.com/u/studiogadget)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/studiogadget/sec-runtime-scan

---


# sec-runtime-scan

**役割**: ランタイム検証専門スキル（静的解析・依存関係スキャンは `/sec-full-scan` が担当）

デプロイ後のサーバーを実際に叩いて「コードを読んでも分からないこと」を検証する。
設定ファイルの反映漏れ・ヘッダーの実際の出力・動的な挙動の確認に特化する。

---

## 引数

| 引数 | 必須 | 説明 |
|------|------|------|
| `環境名` | 任意 | 対象環境（例: `staging`）。省略時は設定ファイルの値を使用 |

## 前提条件

- カレントディレクトリに `security-agent.config.yml` が存在すること
- 環境変数 `STAGING_URL` が設定されていること（未設定なら即時中断）
- **稼働中のサーバーが必要**（このスキルはソースコードを読まない）

---

## 手順

### Step 1: 設定ファイル読み込みと検証

1. `security-agent.config.yml` を読み込み、必須フィールドを確認する
2. 環境変数 `STAGING_URL` の存在確認 → 未設定なら即時中断
3. `target.base_url` に本番 URL パターン（`prod`, `production`, `app.`）が含まれていないか確認 → 含まれていたら即時中断
4. **Prompt Injection 検証**:
   - 文字列フィールドに改行 + 命令語（`ignore`, `system`, `assistant`, `human`）が含まれていないか
   - URL・パスフィールドにシェルメタ文字（`;`, `&&`, `||`, バックティック, `$(...)`）が含まれていないか
   - `scope.include` / `scope.exclude` に `../` が含まれていないか
5. 診断設定の概要を表示する

### Step 2: 攻撃面マッピング

1. `scope.include` / `scope.exclude` を適用して診断対象エンドポイントを確定する
2. `openapi.yml` / `openapi.json` / `swagger.json` があれば読み込んで補完する
3. 診断対象エンドポイント数を報告する

### Step 3: HTTPヘッダー・TLS検証

`curl -I -s {base_url}` でレスポンスヘッダーを取得し、以下を確認する：

| ヘッダー | 期待値 | 欠如時の深刻度 |
|---------|--------|--------------|
| `Strict-Transport-Security` | `max-age≥31536000` | High |
| `X-Content-Type-Options` | `nosniff` | Medium |
| `X-Frame-Options` | `DENY` または `SAMEORIGIN` | Medium |
| `Content-Security-Policy` | 任意のポリシー | Medium |
| `Referrer-Policy` | 設定済み | Low |
| `X-Powered-By` | **存在しないこと** | Low（情報漏洩） |
| `Server` | バージョン番号を含まないこと | Low |

**Critical を発見したら**: 即座にレポートして処理を中断する。

### Step 4: 動的診断

`agents` リストに設定されたエージェントを順番に実行する。
各エージェントの出力は 8,000 文字以内にフィルタしてから処理する。中間結果は都度レポートに追記する。

**owasp_top10**（常に実行）:
- A01: 認証トークンを差し替えて他ユーザーのリソースにアクセス可能か確認
- A02: HTTPS強制・暗号化ヘッダーの確認（Step 3 の結果を参照）
- A03: 入力フィールドへの SQLi / CMDi / NoSQLi ペイロード送信（HTTP レスポンスで確認）
- A05: エラーメッセージ詳細露出・デバッグ情報漏洩の確認
- A07: JWT `alg:none` 攻撃・セッション固定・トークン有効期限チェック
- A10: SSRF パターンのテスト（169.254.169.254 等へのリダイレクト誘導）

**auth_bypass**（設定されている場合）:
- JWT アルゴリズム混乱攻撃（`alg: none` / RS256→HS256）
- OAuth state パラメータ検証
- Cookie の `HttpOnly` / `Secure` / `SameSite` 属性確認

**injection**（設定されている場合）:
- SQL インジェクション（時間ベース盲目的・エラーベース）
- NoSQL インジェクション（`$where`, `$regex`, `$gt`）
- コマンドインジェクション（`;ls`, `&&id` 等）

**prompt_injection**（設定されている場合）:
- Direct Injection: システムプロンプト上書き試行
- Indirect Injection: 外部データ経由の指示埋め込みテスト

**multi_tenant**（設定されている場合）:
- 他テナント ID への直接アクセス試行
- レスポンスデータに他テナントデータが含まれないか確認

**file_exposure**（設定されている場合）:
- パストラバーサル（`../../../etc/passwd`）
- 公開 URL の推測（連番・UUID パターン）

### Step 5: カバレッジ集計

```yaml
scan_date: <ISO8601>
target: <base_url>
scan_type: runtime

attack_surface:
  endpoints_total: <総数>
  endpoints_tested: <テスト済み数>
  endpoints_skipped:
    - path: <パス>
      reason: <理由>

vuln_classes:
  owasp_top10:
    covered: <N>/10
    gaps:
      - <カバーできなかった項目と理由>

findings:
  critical: <件数>
  high: <件数>
  medium: <件数>
  low: <件数>

not_covered_by_this_scan:
  - 依存関係の既知CVE → /sec-full-scan を使用
  - ソースコードの静的解析 → /sec-full-scan を使用
  - ビジネスロジックの欠陥 → ペネトレーションテスト（人手）が必要
  - インフラ・クラウド設定 → インフラ担当者によるレビューが必要

coverage_score: <パーセンテージ>
ci_result: <pass/fail>
```

### Step 6: レポート生成・履歴インデックス更新

1. **日付付きファイル名でレポートを保存する**
   - レポート: `./security-reports/YYYY-MM-DD-security-scan-report.md`
   - カバレッジ: `./security-reports/YYYY-MM-DD-security-scan-coverage.yml`
   - 日付は実行時の ISO 8601 形式（例: `2026-05-01`）
   - `report.output_path` が明示指定されている場合はそちらを優先する
   - ディレクトリが存在しない場合は作成する

2. 深刻度別にソートし、修正推奨事項を含める

3. **`./security-reports/index.md` に1行追記する**
   - ファイルが存在しない場合はヘッダーから作成する
   - 追記フォーマット:
   ```
   | YYYY-MM-DD | sec-runtime-scan | <base_url> | <Critical件数> | <High件数> | <Medium件数> | <CI結果> | [レポート](YYYY-MM-DD-security-scan-report.md) |
   ```
   - CI結果: `findings.critical > 0` または `severity_gate` 基準以上なら `❌ fail`、それ以外は `✅ pass`

4. `findings.critical > 0` または `severity_gate` 基準以上の発見がある場合、終了コード 1 を報告する

---

## このスキルでカバーできない領域

| 領域 | 推奨手段 |
|------|---------|
| 依存関係の既知 CVE | `/sec-full-scan` |
| ソースコードの静的解析 | `/sec-full-scan` |
| PR 差分の脆弱性 | `/sec-diff-review` |
| ビジネスロジックの欠陥 | ペネトレーションテスト |
| インフラ・クラウド設定 | インフラ担当者レビュー |

---

## 完了条件

- [ ] `./security-reports/YYYY-MM-DD-security-scan-report.md` が生成されている
- [ ] `./security-reports/YYYY-MM-DD-security-scan-coverage.yml` が生成されている（`scan_type: runtime` 明記）
- [ ] 診断済み OWASP カテゴリ数が報告されている
- [ ] `severity_gate` 基準に基づく CI 結果（pass / fail）が明示されている
- [ ] **カバーできない領域**が明示されている
- [ ] `./security-reports/index.md` に1行追記されている

