# セキュリティ設計書

## 概要

本ドキュメントは、mruby（軽量Ruby実装）のセキュリティ設計を記載したものである。mrubyはC言語で実装された組み込み向けスクリプトエンジンであり、セキュリティモデルは**ホストアプリケーションとの協調設計**を前提としている。mruby自体は型安全性・メモリ安全性・リソース制限に責任を持ち、認証・認可・サンドボックスなどの上位セキュリティ機能はホストアプリケーションに委譲する設計となっている。

## 認証設計

### 認証方式

mrubyはスクリプト実行エンジンであり、認証機能は実装されていない。認証はホストアプリケーションが責任を持つ設計となっている（`SECURITY.md`に明記）。

ホストアプリケーションは以下を保証する責任がある：

- 信頼できるソースからのバイトコード（`.mrb`ファイル）のみを実行すること
- mrubyスクリプトの実行権限を適切に管理すること
- `mrb_state`のライフサイクルをセキュアに管理すること

### セッション管理

| 項目 | 設定値 | 備考 |
| --- | --- | --- |
| セッション管理 | ホストアプリケーションに委譲 | mruby自体はセッション概念を持たない |
| `mrb_state`ライフサイクル | ホスト管理 | `mrb_open()` / `mrb_close()`で生成・破棄 |

## 認可設計

### 権限体系

| ロール | 権限 | 説明 |
| --- | --- | --- |
| ホストアプリケーション | 全権限 | C APIを通じてmrubyの全機能にアクセス可能 |
| mrubyスクリプト | 制限付き | ホストが公開したメソッド・クラスのみアクセス可能 |
| バイトコード | 実行権限のみ | 信頼できるソースから生成されたバイトコードの実行 |

### アクセス制御

mrubyのアクセス制御はC APIレベルで実現される。ホストアプリケーションが`mrb_define_method()`等で公開するメソッドを制御することで、mrubyスクリプトからアクセス可能な機能を制限できる。

**型チェックによるアクセス制御**（`src/vm.c`）:

VM内での演算時に型チェックが行われ、不正な型の値による操作を防止する。

```c
#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
uint16_t tt = TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]));
```

**読み取り専用データ検出**（`include/mruby/value.h`）:

プラットフォーム別に読み取り専用メモリ領域を自動検出し、不正な書き込みを防止する。

- Linux: `etext` / `edata`セグメント境界を使用
- macOS: `mach-o/getsect.h`で`SEG_TEXT`を検出
- カスタム実装: `MRB_USE_CUSTOM_RO_DATA_P`で独自実装が可能

## 通信セキュリティ

| 項目 | 対策 |
| --- | --- |
| HTTPS | mruby自体は通信層を持たない。ホストアプリケーションに委譲 |
| HSTS | 同上 |

mrubyはスクリプト実行エンジンであり、通信機能は標準では含まれない。ネットワーク通信が必要な場合は、ホストアプリケーションまたはmrbgemsを通じて実装する。

## データセキュリティ

### 暗号化

| 対象 | 暗号化方式 |
| --- | --- |
| 通信 | ホストアプリケーションに委譲（mrubyは通信層を持たない） |
| 保存データ（バイトコード） | 暗号化なし（平文RITE形式）。ホストが信頼できるソースからの実行を保証 |
| ハッシュ | `mrb_str_hash()` / `mrb_obj_hash_code()`（暗号学的安全性は保証しない、内部データ構造用） |

**バイトコード形式**（`include/mruby/dump.h`）:

```
RITE形式: "RITE" + バージョン + バイナリサイズ + コンパイラ情報
```

バイトコードは暗号化・署名されない設計であり、`SECURITY.md`にて「バイトコード形式はセキュリティ境界ではない」と明記されている。

### 機密情報管理

mrubyは機密情報管理機能を持たない。以下はホストアプリケーションの責任となる：

- バイトコードの安全な配信・保管
- mrubyスクリプトから機密情報へのアクセス制御
- `mrb_state`内のデータの保護
- デバッグ情報（`MRB_DUMP_DEBUG_INFO`）の本番環境での無効化

## 入出力対策

| 脅威 | 対策 |
| --- | --- |
| バッファオーバーフロー | 文字列長チェック（`str_check_length()`）、配列サイズチェック（`ary_check_too_big()`）、`mrb_read_irep_buf()`によるサイズ指定付きバイトコード読み込み |
| 整数オーバーフロー | `mrb_int_add_overflow()` / `mrb_int_sub_overflow()` / `mrb_int_mul_overflow()`による安全な演算。GCC/Clang builtin関数対応 |
| リソース枯渇（DoS） | `MRB_STR_LENGTH_MAX`（デフォルト1MB）、`MRB_ARY_LENGTH_MAX`（デフォルト131,072要素）によるサイズ制限 |
| 型混同攻撃 | `mrb_check_type()` / `mrb_ensure_string_type()`等による動的型チェック |
| 不正バイトコード実行 | バイトコード形式のバージョンチェック、ヘッダ検証。ただし完全な検証はホストの責任 |
| use-after-free | 三色増分GCとWrite Barrierによるメモリ安全性保証 |

### 入力検証の詳細

**文字列長チェック**（`src/string.c:40-51`）:

```c
static void str_check_length(mrb_state *mrb, mrb_int len) {
  if (len < 0 || len == MRB_INT_MAX) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative (or overflowed) string size");
  }
}
```

**配列サイズチェック**（`src/array.c:17-42`）:

```c
#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
static void ary_check_too_big(mrb_state *mrb, mrb_int a, mrb_int b) {
  if (a > ARY_MAX_SIZE - b || a < 0) ary_too_big(mrb);
}
```

**整数パース検証**（`src/readint.c:11-27`）:

各演算段階で`mrb_int_mul_overflow()` / `mrb_int_add_overflow()`によるオーバーフロー検出を実施。

## メモリ安全性設計

### ガベージコレクション

mrubyは**三色増分ガベージコレクション**（Tri-color Incremental GC）を実装している（`src/gc.c`）。

| 項目 | 内容 |
| --- | --- |
| GCアルゴリズム | 三色増分マーク&スイープ |
| オブジェクト色 | White（未マーク）、Gray（マーク済・子未マーク）、Black（完全マーク）、Red（静的ROMオブジェクト） |
| Write Barrier | `mrb_field_write_barrier()` / `mrb_write_barrier()`による参照更新の一貫性保証 |
| 世代別GC | `MRB_GC_TURN_OFF_GENERATIONAL`で制御可能 |
| アリーナ保護 | `MRB_GC_ARENA_SIZE`（デフォルト100）でGC保護領域を管理 |
| gray_overflow検出 | `MRB_GRAY_STACK_SIZE`（デフォルト1024）超過時にヒープ再スキャンを実施 |

### メモリ割り当て

- `mrb_basic_alloc_func()`（`src/allocf.c`）: 標準CRT関数（`malloc`/`realloc`/`free`）を使用
- ホスト側でカスタム割り当て関数を指定可能（`mrb_open_allocf()`）
- `size == 0`の場合は`free()`を実行しNULLを返す安全な実装

### 文字列・配列の安全な実装

| データ構造 | セキュリティ機構 |
| --- | --- |
| 文字列（`RString`） | 埋め込み文字列（`RSTR_EMBED_P()`）で小文字列をヒープ外に格納、共有文字列（Copy-on-Write）、`len`/`capa`による境界追跡 |
| 配列（`RArray`） | 埋め込み配列（`MRB_ARY_EMBED_LEN_MAX`）、共有配列（参照カウント）、`ARY_SET_LEN()`マクロで長さ検証 |

## 監査ログ

| ログ種別 | 記録内容 | 保持期間 |
| --- | --- | --- |
| デバッグフック | `MRB_USE_DEBUG_HOOK`有効時にVM実行フックを提供 | ホストアプリケーションで制御 |
| バックトレース | メソッド名、行番号、IREPへの参照（`RBacktrace`構造体） | `mrb_state`のライフサイクル内 |
| デバッグ情報ダンプ | `MRB_DUMP_DEBUG_INFO`フラグでバイトコードへのデバッグ情報埋め込みを制御 | バイトコードファイルの寿命 |
| ローカル変数情報 | `MRB_DUMP_NO_LVAR`フラグでローカル変数情報の除外が可能（情報漏洩防止） | バイトコードファイルの寿命 |

mruby自体は監査ログ機能を持たない。ホストアプリケーションがデバッグフックやバックトレース情報を活用してログを記録する設計となっている。

## セキュリティ設定一覧

### コンパイルオプション（`include/mrbconf.h`）

| オプション | デフォルト値 | セキュリティ意義 |
| --- | --- | --- |
| `MRB_STR_LENGTH_MAX` | 1,048,576（1MB） | DoS対策：文字列サイズ制限 |
| `MRB_ARY_LENGTH_MAX` | 131,072 | DoS対策：配列サイズ制限 |
| `MRB_GC_ARENA_SIZE` | 100 | GC保護領域のサイズ |
| `MRB_GRAY_STACK_SIZE` | 1,024 | GCグレースタックサイズ（オーバーフロー検出） |
| `MRB_USE_DEBUG_HOOK` | OFF | デバッガフック（本番環境では無効推奨） |
| `MRB_DUMP_DEBUG_INFO` | ビルド時指定 | デバッグ情報の埋め込み（本番環境では除外推奨） |
| `MRB_DUMP_NO_LVAR` | ビルド時指定 | ローカル変数情報の除外（情報漏洩防止） |
| `MRB_NO_STDIO` | OFF | 標準入出力の除外（サンドボックス強化） |
| `MRB_USE_BIGINT` | OFF | 多倍長整数サポート（整数オーバーフロー自動昇格） |
| `MRB_GC_TURN_OFF_GENERATIONAL` | OFF | 世代別GCの無効化 |
| `MRB_GC_FIXED_ARENA` | OFF | GCアリーナの固定サイズ化 |
| `MRB_USE_CUSTOM_RO_DATA_P` | OFF | 読み取り専用データ検出のカスタム実装 |

### 非推奨API

| API | 代替 | 理由 |
| --- | --- | --- |
| `mrb_read_irep()` | `mrb_read_irep_buf()` | サイズ指定なしのためバッファオーバーフローの可能性 |

### セキュリティテスト

`oss-fuzz/`ディレクトリにOSS-Fuzz統合が存在し、継続的なファジングテストが実施されている。

## セキュリティ責任の分界

### mrubyが責任を持つ範囲

- 型安全性（動的型チェック、値型の検証）
- メモリ安全性（三色増分GC、Write Barrier、use-after-free対策）
- 整数オーバーフロー検出（builtin関数による安全な演算）
- リソース制限（文字列・配列のサイズ制限によるDoS防止）
- アサーション検証（VM状態・IREP妥当性・スタック境界の一貫性チェック）

### ホストアプリケーションが責任を持つ範囲

- 認証・認可
- バイトコード検証（信頼できるソースからの実行保証）
- リソース制限（CPU時間、メモリ使用量の上限）
- サンドボックス機構
- 暗号化通信
- 機密情報管理
- 監査ログの記録と保管

### セキュリティアーキテクチャ

```
[外部入力]
    ↓
[ホストアプリケーション: 認証・認可・入力検証]
    ↓
[mruby構文解析: 構文検証・型チェック]
    ↓
[VM実行: 型チェック・整数オーバーフロー検証・スタック境界チェック]
    ↓
[GC: メモリ安全性・Write Barrier・世代別管理]
```

## 備考

- mrubyのセキュリティモデルは`SECURITY.md`に明示されており、高優先度の脆弱性はRemote Code Execution（RCE）のみと定義されている
- 不正なバイトコード（`.mrb`ファイル）によるクラッシュはセキュリティ脆弱性としては扱われない（バイトコード形式はセキュリティ境界ではないため）
- 暗号化ライブラリは標準では含まれず、必要に応じてmrbgemsとして追加する設計
- OSS-Fuzzによる継続的なファジングテストが実施されている
