# 画面設計書 12-ホストブロック画面

## 概要

本ドキュメントは、Ruby on Railsフレームワークにおける「ホストブロック画面」の設計仕様を定義する。許可されていないホストからのリクエストがブロックされた際に表示されるセキュリティ関連のエラー画面である。

### 本画面の処理概要

この画面は、RailsアプリケーションのHostAuthorizationミドルウェアによって、許可されていないホストからのリクエストがブロックされた際に表示されるエラー画面である。DNSリバインディング攻撃からアプリケーションを保護するためのセキュリティ機能の一部として機能する。

**業務上の目的・背景**：DNSリバインディング攻撃は、悪意のあるWebサイトがブラウザの同一オリジンポリシーを回避して内部ネットワークリソースにアクセスする攻撃手法である。Rails 6.0以降、HostAuthorizationミドルウェアがデフォルトで有効になり、明示的に許可されたホスト以外からのリクエストをブロックする。この画面は、ブロックの原因と解決方法を開発者に提示することで、セキュリティを維持しながら迅速な設定修正を可能にする。

**画面へのアクセス方法**：`config.hosts`に許可されていないホスト名でアプリケーションにアクセスした際に、自動的にこの画面が表示される。例えば、`config.hosts << "localhost"`のみが設定されている状態で、`192.168.1.1`からアクセスした場合に表示される。

**主要な操作・処理内容**：
1. ブロックされたホスト名の表示 - リクエストヘッダーから取得したホスト名を明示
2. 設定方法の案内 - `config.hosts`への追加方法をコード例とともに提示
3. ドキュメントへのリンク - Rails Guidesの該当セクションへのリンクを提供
4. 複数ホストの対応 - 複数のホストがブロックされた場合、すべてを列挙

**画面遷移**：
- 遷移元：許可されていないホストからのHTTPリクエスト
- 遷移先：Rails Guides「Host Authorization」ページ（外部リンク）

**権限による表示制御**：
- 開発環境（`config.consider_all_requests_local = true`）でのみ詳細情報が表示される
- 本番環境では空のボディで403 Forbiddenレスポンスが返される

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | Content Security Policy | 主機能 | 許可されていないホストのブロック処理 |
| 26 | Debug Exceptions | 補助機能 | ブロック原因の説明と設定方法の案内 |

## 画面種別

エラー診断（開発環境専用）

## URL/ルーティング

特定のURLは存在しない。HostAuthorizationミドルウェアがリクエストをブロックした際に本画面を表示する。

例：
- 任意のURLへのリクエスト（許可されていないホストからのアクセス時）

## 入出力項目

本画面はエラー診断画面のため、ユーザー入力項目は存在しない。

| 項目 | 入出力 | 説明 |
|------|--------|------|
| なし | - | ユーザー入力を受け付けない |

## 表示項目

| 項目名 | データ型 | 説明 | ソース |
|--------|----------|------|--------|
| ヘッダータイトル | String | "Blocked hosts: {ホスト名}" | `@hosts.join(", ")` |
| 設定案内 | String | config.hostsへの追加方法の説明 | テンプレート固定文字列 |
| 設定コード例 | String | 許可設定のサンプルコード | `@hosts`を基に動的生成 |
| ドキュメントリンク | URL | Rails Guidesへのリンク | 固定URL |

## イベント仕様

### 1-ドキュメントリンク押下

**処理内容**：Rails Guidesの「Host Authorization」セクションを新しいタブで開く。

**トリガー**：ドキュメントリンクのクリック

**処理フロー**：
1. ユーザーがリンクをクリック
2. ブラウザが外部URL（https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization）を開く

**画面遷移**：外部サイトへ遷移（新規タブ）

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| なし | なし | なし | 本画面はデータベースへの操作を行わない |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG-001 | エラー | "Blocked hosts: {ホスト名}" | 常時ヘッダーに表示 |
| MSG-002 | 情報 | "To allow requests to these hosts..." | 常時本文に表示 |
| MSG-003 | 情報 | 'config.hosts << "{ホスト名}"' | ブロックされた各ホストに対して表示 |

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|---------|---------|---------|
| ホストブロック | 許可されていないホストからのリクエスト | 本画面を表示（開発環境）/空の403レスポンス（本番環境） |

## 備考

- HostAuthorizationミドルウェアはRails 6.0以降でデフォルト有効
- 開発環境では `.localhost` と `.test` ドメイン、すべてのIPアドレスがデフォルトで許可される
- `config.host_authorization = { exclude: ->(request) { ... } }` でリクエスト単位の除外が可能
- HTTPステータスコード403（Forbidden）で応答する
- X-Forwarded-Hostヘッダーも検証対象に含まれる

---

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

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

### 推奨読解順序

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

まず、ホスト許可の仕組みとPermissionsクラスの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | host_authorization.rb | `actionpack/lib/action_dispatch/middleware/host_authorization.rb` | Permissionsクラス、allows?メソッド、ホスト検証ロジック |

**読解のコツ**: 35-86行目のPermissionsクラスで、ホスト許可の検証ロジックを確認する。sanitize_hosts、sanitize_string、sanitize_regexpメソッドでホストパターンの正規化処理を理解する。

#### Step 2: エントリーポイントを理解する

処理の起点となるHostAuthorizationミドルウェアを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | host_authorization.rb | `actionpack/lib/action_dispatch/middleware/host_authorization.rb` | ミドルウェアのcallメソッド、ブロック判定の流れ |

**主要処理フロー**:
1. **127-133行目**: `initialize`でPermissionsオブジェクトとresponse_appを初期化
2. **135-148行目**: `call`メソッドでホスト検証を実行
3. **151-161行目**: `blocked_hosts`でブロック対象ホストを特定
4. **145-146行目**: ブロック時に`action_dispatch.blocked_hosts`をenvに設定し、response_appを呼び出す

#### Step 3: レスポンス生成を理解する

ブロック時のレスポンス生成ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | host_authorization.rb | `actionpack/lib/action_dispatch/middleware/host_authorization.rb` | DefaultResponseAppクラス |
| 3-2 | blocked_host.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb` | 表示テンプレート |

**主要処理フロー**:
- **88-125行目（DefaultResponseApp）**: デフォルトのレスポンス生成アプリケーション
- **91-97行目**: `call`メソッドでHTMLレスポンスを生成
- **100-105行目**: `response_body`で詳細表示の判定とDebugView使用
- **1-13行目（blocked_host.html.erb）**: ブロックされたホストの表示と設定案内

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

```
HTTPリクエスト
    │
    ├─ HostAuthorization#call（host_authorization.rb:135）
    │      │
    │      ├─ Permissions#allows?（host_authorization.rb:44）
    │      │      └─ ホスト検証
    │      │
    │      ├─ blocked_hosts（host_authorization.rb:151）
    │      │      ├─ HTTP_HOST検証
    │      │      └─ X-Forwarded-Host検証
    │      │
    │      └─ ブロック判定
    │             │
    │             ├─ 許可 → @app.call(env)
    │             │
    │             └─ ブロック → DefaultResponseApp#call
    │                    │
    │                    ├─ log_error（host_authorization.rb:114）
    │                    │
    │                    └─ response_body（host_authorization.rb:100）
    │                           │
    │                           ├─ show_detailed_exceptions判定
    │                           │      │
    │                           │      ├─ true → DebugView + blocked_host.html.erb
    │                           │      │
    │                           │      └─ false → 空のボディ
    │                           │
    │                           └─ response（403 Forbidden）
    │
    └─ HTTPレスポンス
```

### データフロー図

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

HTTPリクエスト ───────▶ HostAuthorization
   │                          │
   ├─ HTTP_HOST               ├─ Permissions#allows?
   │                          │      │
   └─ X-Forwarded-Host        │      └─ ホスト検証
                              │
                              ▼
                         ブロック判定
                              │
                    ┌─────────┴─────────┐
                    │                   │
                    ▼                   ▼
              許可 → 通常処理     ブロック → DefaultResponseApp
                                        │
                                        ▼
                                  action_dispatch.blocked_hosts
                                    = ["blocked.host"]
                                        │
                                        ▼
                                  DebugView
                                    - @hosts: ブロックされたホスト配列
                                        │
                                        ▼
                                  blocked_host.html.erb ───────▶ HTMLレスポンス
                                                                   (403 Forbidden)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| host_authorization.rb | `actionpack/lib/action_dispatch/middleware/host_authorization.rb` | ソース | ホスト認可ミドルウェア |
| blocked_host.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb` | テンプレート | ホストブロックエラー画面テンプレート |
| _copy_button.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/_copy_button.html.erb` | テンプレート | コピーボタンパーシャル |
| layout.html.erb | `actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb` | テンプレート | エラー画面共通レイアウト |
