# 機能設計書 65-脆弱性スキャン

## 概要

本ドキュメントは、GitLabにおける脆弱性スキャン機能の設計仕様を記載する。SAST（Static Application Security Testing）、DAST（Dynamic Application Security Testing）、コンテナスキャン等のセキュリティスキャン機能により、ソースコードやコンテナイメージの脆弱性を検出する。

### 本機能の処理概要

脆弱性スキャン機能は、CI/CDパイプライン内でセキュリティスキャナを実行し、検出された脆弱性をGitLab上で一元管理するための機能である。複数のスキャンタイプをサポートし、検出結果をマージリクエストやセキュリティダッシュボードで表示する。

**業務上の目的・背景**：セキュアなソフトウェア開発において、早期に脆弱性を発見し修正することは重要である。本機能により、開発プロセスにセキュリティスキャンを統合（DevSecOps）し、脆弱性の早期発見・対応を実現する。手動でのセキュリティ監査に比べ、自動化されたスキャンにより継続的かつ網羅的なセキュリティチェックが可能となる。

**機能の利用シーン**：
- コードプッシュ時のSAST（静的アプリケーションセキュリティテスト）
- マージリクエストでの脆弱性レポート表示
- デプロイ前のDASTによる動的テスト
- コンテナイメージの脆弱性スキャン
- セキュリティダッシュボードでの脆弱性管理

**主要な処理内容**：
1. CI/CDパイプラインでのスキャナ実行
2. スキャン結果（JSONレポート）の解析・取り込み
3. 脆弱性Finding（検出項目）の生成・保存
4. マージリクエストでの差分表示
5. 脆弱性ステータスの管理（detected, confirmed, resolved, dismissed）
6. 重大度・信頼度に基づく優先度付け

**関連システム・外部連携**：
- GitLab Runner（スキャナ実行）
- 各種セキュリティスキャナ（Semgrep、Trivy、ZAP等）
- NVD（National Vulnerability Database）
- CVE（Common Vulnerabilities and Exposures）

**権限による制御**：
- `read_security_configuration`権限：セキュリティ設定の閲覧
- `read_vulnerability`権限：脆弱性情報の閲覧
- `admin_vulnerability`権限：脆弱性ステータスの変更

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 125 | セキュリティ設定 | 主機能 | セキュリティ設定の管理 |

## 機能種別

データ解析 / レポート生成 / バリデーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| report_type | String | Yes | スキャンタイプ（sast, dast, container_scanning等） | enum値 |
| report_file | JSON | Yes | スキャン結果のJSONファイル | スキーマバリデーション |

### 入力データソース

- CI/CDジョブのアーティファクト（gl-sast-report.json等）
- セキュリティスキャナの出力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | Integer | 脆弱性ID |
| uuid | String | 一意識別子 |
| name | String | 脆弱性名 |
| severity | String | 重大度（info, unknown, low, medium, high, critical） |
| confidence | String | 信頼度（ignore, unknown, experimental, low, medium, high, confirmed） |
| state | String | 状態（detected, confirmed, resolved, dismissed） |
| report_type | String | スキャンタイプ |
| location | Object | 検出場所（ファイルパス、行番号等） |
| identifiers | Array | 識別子（CVE、CWE等） |

### 出力先

- データベース（vulnerabilitiesテーブル）
- マージリクエストウィジェット
- セキュリティダッシュボード
- JSONレポート

## 処理フロー

### 処理シーケンス

```
1. CI/CDパイプライン実行
   └─ セキュリティスキャナジョブ実行
   └─ JSONレポートファイル生成

2. レポート解析
   └─ パーサーによるJSON解析
   └─ Findingオブジェクト生成
   └─ 識別子・スキャナ情報の抽出

3. 脆弱性登録
   └─ 既存Findingとの重複チェック
   └─ 新規Findingの作成
   └─ Vulnerabilityレコードの作成/更新

4. 表示
   └─ マージリクエストウィジェットでの差分表示
   └─ セキュリティダッシュボードでの一覧表示
```

### フローチャート

```mermaid
flowchart TD
    A[CI/CDパイプライン] --> B[スキャナジョブ実行]
    B --> C[JSONレポート生成]
    C --> D[レポート解析]
    D --> E[Finding生成]
    E --> F{既存Finding存在?}
    F -->|Yes| G[更新処理]
    F -->|No| H[新規作成]
    G --> I[Vulnerability更新]
    H --> I
    I --> J[MRウィジェット表示]
    I --> K[ダッシュボード表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 重大度レベル | info, unknown, low, medium, high, criticalの6段階 | 全Finding |
| BR-02 | 信頼度レベル | ignore, unknown, experimental, low, medium, high, confirmedの7段階 | 全Finding |
| BR-03 | 状態遷移 | detected -> confirmed/resolved/dismissed | ステータス変更時 |
| BR-04 | OWASP分類 | OWASP Top 10（2017/2021）に基づく分類 | 識別子存在時 |
| BR-05 | UUID生成 | 一意のUUIDでFindingを識別 | Finding作成時 |
| BR-06 | 署名ベース重複検出 | 署名情報を使用したFinding同一性判定 | 重複チェック時 |

### 計算ロジック

- 重大度による優先度ソート: critical > high > medium > low > unknown > info
- Findingのハッシュ計算: `report_type.hash ^ location.fingerprint.hash ^ primary_identifier_fingerprint.hash`

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| スキャン結果取り込み | vulnerability_findings | INSERT | 検出項目の保存 |
| 脆弱性作成 | vulnerabilities | INSERT | 脆弱性レコードの作成 |
| ステータス更新 | vulnerabilities | UPDATE | 状態変更 |
| 識別子登録 | vulnerability_identifiers | INSERT | CVE/CWE等の識別子 |

### テーブル別操作詳細

#### vulnerabilities

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | project_id | 対象プロジェクトID | 外部キー |
| INSERT | state | 1（detected） | 初期状態 |
| INSERT | severity | Findingのseverity | enum値 |
| INSERT | confidence | Findingのconfidence | enum値 |
| INSERT | report_type | スキャンタイプ | enum値 |
| UPDATE | state | 1-4（状態遷移） | 手動/自動更新 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | スキーマバリデーションエラー | JSONが規定スキーマに適合しない | レポート形式を確認 |
| - | パースエラー | JSON解析失敗 | レポートファイルを確認 |

### リトライ仕様

レポート解析エラー時、ジョブ自体のリトライ機構を使用。

## トランザクション仕様

- Finding作成とVulnerability作成は同一トランザクション
- 大量のFinding処理時はバッチ処理

## パフォーマンス要件

- プロジェクトあたりの脆弱性取得は10,000件まで

## セキュリティ考慮事項

- 脆弱性情報は機密性が高いため、適切なアクセス制御が必要
- CVSSベクトルのバリデーション

## 備考

- 本機能の大部分はGitLab EE（Enterprise Edition）で提供
- feature_category: `static_application_security_testing`（SAST）、`dynamic_application_security_testing`（DAST）等

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

脆弱性スキャンで使用される主要なデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | vulnerability.rb | `app/models/vulnerability.rb` | 脆弱性のActiveRecordモデル（EEで拡張） |
| 1-2 | vulnerability.rb (enum) | `app/models/concerns/enums/vulnerability.rb` | 重大度・信頼度・状態のenum定義 |

**読解のコツ**:
- **enums/vulnerability.rb 5-14行目**: 信頼度レベルの定義
- **enums/vulnerability.rb 21-30行目**: 重大度レベルの定義
- **enums/vulnerability.rb 43-48行目**: 脆弱性状態の定義
- **enums/vulnerability.rb 50-86行目**: OWASP Top 10の分類定義

#### Step 2: レポート解析を理解する

CI/CDジョブが出力するJSONレポートの解析処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | report.rb | `lib/gitlab/ci/reports/security/report.rb` | セキュリティレポートクラス |
| 2-2 | finding.rb | `lib/gitlab/ci/reports/security/finding.rb` | 検出項目クラス |

**主要処理フロー**:
- **report.rb 17-26行目**: コンストラクタでレポート初期化
- **report.rb 52-54行目**: `add_finding`でFinding追加
- **finding.rb 11-21行目**: Findingの必須キー定義
- **finding.rb 116-124行目**: `eql?`メソッドでFinding同一性判定
- **finding.rb 135-137行目**: `valid?`メソッドでFinding検証

#### Step 3: コントローラー層を理解する

Web UIからのセキュリティ設定アクセスを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | configuration_controller.rb | `app/controllers/projects/security/configuration_controller.rb` | セキュリティ設定コントローラー |

**主要処理フロー**:
- **11-22行目**: `show`アクションでセキュリティ設定表示
- **12行目**: `read_security_configuration`権限チェック

### プログラム呼び出し階層図

```
CI/CD Pipeline
    │
    ├─ Security Scanner Job
    │      └─ gl-{type}-report.json 生成
    │
    └─ Report Processing
           └─ Gitlab::Ci::Parsers::Security::*
                  └─ Report.add_finding
                         └─ Finding 作成
                                │
                                ▼
                    Security::StoreReportService（EE）
                           └─ Vulnerability 作成/更新
                                  └─ vulnerabilities テーブル
```

### データフロー図

```
[入力]                    [処理]                           [出力]

Security Scanner ────▶ JSON Report ──────────────────▶ vulnerabilities
(Semgrep, Trivy等)      (gl-*-report.json)               (PostgreSQL)
                              │                              │
                              ▼                              ▼
                    Gitlab::Ci::Parsers::*           MR Widget / Dashboard
                    (レポート解析)                    (UI表示)
                              │
                              ▼
                    Security::Finding
                    (検出項目オブジェクト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| vulnerability.rb | `app/models/vulnerability.rb` | モデル | 脆弱性モデル |
| vulnerability.rb (enum) | `app/models/concerns/enums/vulnerability.rb` | Concern | enum定義 |
| report.rb | `lib/gitlab/ci/reports/security/report.rb` | ライブラリ | レポートクラス |
| finding.rb | `lib/gitlab/ci/reports/security/finding.rb` | ライブラリ | 検出項目クラス |
| configuration_controller.rb | `app/controllers/projects/security/configuration_controller.rb` | コントローラー | セキュリティ設定 |
| scanner.rb | `lib/gitlab/ci/reports/security/scanner.rb` | ライブラリ | スキャナ情報 |
| identifier.rb | `lib/gitlab/ci/reports/security/identifier.rb` | ライブラリ | 識別子（CVE/CWE） |
| locations/sast.rb | `lib/gitlab/ci/reports/security/locations/sast.rb` | ライブラリ | SAST位置情報 |
