Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

セキュリティモデル

zwasm は、ゲスト(WebAssembly モジュール)とホスト(組み込みアプリケーションまたは CLI)の間に明確な境界を設けています。

信頼境界

+-------------------+    WASI capabilities    +------------------+
|   Guest (Wasm)    | <-- deny-by-default --> |  Host (Zig/CLI)  |
|                   |                         |                  |
| Linear memory     |    Imports/exports      | Native memory    |
| Table entries     | <-- validated types --> | Filesystem, env  |
| Global variables  |                         | Network, OS APIs |
+-------------------+                         +------------------+

正当な Wasm モジュールは、どれほど悪意のあるものであっても、以下のことはできません:

  • 自身のリニアメモリ外のホストメモリを読み書きする
  • 明示的にインポートされていないホスト関数を呼び出す
  • WASI のケーパビリティ制限を回避する
  • バリデーション済みの命令ストリーム外のコードを実行する
  • トラップを発生させずにコールスタックまたはバリュースタックをオーバーフローさせる

防御レイヤー

モジュールデコード

すべてのバイナリ入力は境界チェックされます。リソース制限により過剰なアロケーションを防止します:

  • セクション数: セクションタイプごとに 100〜100,000
  • 関数あたりのローカル変数: 最大 50,000(オーバーフロー対策として飽和演算を使用)
  • ブロックのネスト深度: 500
  • LEB128 の読み取りはバイナリスライスに対して境界チェック済み

バリデーション

コード実行前に Wasm 3.0 の完全な型チェックを行います。62,158 件の spec テストにより正確性を検証しています。

リニアメモリの分離

  • すべての load/store は u33 演算(address + offset)を使用し、32 ビットオーバーフローを防止
  • ガードページ: 4 GiB + 64 KiB の PROT_NONE 領域により、すべての範囲外アクセスを捕捉
  • シグナルハンドラがメモリフォルトを Wasm トラップに変換

JIT セキュリティ

  • W^X: コードページはコンパイル中は RW で、実行前に RX に切り替え。書き込み可能と実行可能が同時に有効になることはありません。
  • すべての分岐ターゲットはレジスタ IR に対してバリデーション済み
  • シグナルハンドラが JIT コード内のフォルトを Wasm トラップに変換

WASI ケーパビリティ

デフォルト拒否モデルで、8 つのケーパビリティフラグがあります:

フラグ制御対象
allow-readファイルシステムの読み取り
allow-writeファイルシステムの書き込み
allow-env環境変数
allow-pathパス操作(open, mkdir, unlink)
allow-clockクロックアクセス
allow-random乱数生成
allow-procプロセス操作
allow-all上記すべて

46 個の WASI 関数のうち 32 個が実行前にケーパビリティをチェックします。残りの 14 個は安全な操作(args のサイズ照会、fd_close など)です。

ライブラリ API のデフォルトloadWasi()): cli_default — stdio、clock、random、proc_exit のみ。フルアクセスが必要なエンベッダは loadWasiWithOptions(.{ .caps = .all }) を使用します。

--sandbox モード: すべてのケーパビリティを拒否し、fuel を 10 億命令に設定し、メモリ上限を 256MB に制限します。--allow-* フラグと組み合わせて選択的にアクセスを許可できます:

zwasm untrusted.wasm --sandbox --allow-read --dir ./data

--env KEY=VALUE: 注入された環境変数は、--allow-env がなくてもゲストから常にアクセス可能です。--allow-env フラグはホスト環境のパススルーアクセスを制御します。

スタック保護

  • コール深度の制限: 1024(すべての呼び出し時にチェック)
  • オペランドスタック: 固定サイズ配列、境界チェック済み
  • ラベルスタック: 境界チェック済み

zwasm が保護しないもの

  • タイミングサイドチャネル: 定数時間の保証なし
  • リソース枯渇: モジュールが無限ループする可能性あり(--fuel で軽減)
  • ホスト関数のバグ: ホスト関数に脆弱性がある場合、Wasm コードがそれを引き起こす可能性あり
  • Spectre/Meltdown: ハードウェアレベルの軽減策なし
  • タイミングによる情報漏洩: JIT コンパイル時間はコード構造によって異なる可能性あり

推奨事項

  • 本番環境では ReleaseSafe でビルド(Zig の境界チェック + オーバーフロー検出)
  • 信頼できないモジュールには --fuel を使用して無限ループを防止
  • --max-memory でメモリ使用量を制限
  • モジュールに必要な WASI ケーパビリティのみを付与
  • 脆弱性の報告については SECURITY.md を参照