Storybookの開発サーバーは、ローカルネットワークからのコードインジェクションの脆弱性があります。

**概要:** Storybookの開発サーバーは、HTMLページを読み込むことができるすべてのクライアントに対して、WebSocket認証トークンを公開しています。LAN内のどのホストでも、IPアドレスでStorybookアプリケーションを開くことができ、それによってトークンを取得できます。このWebSocketを使用して、ストーリーファイルにコードを注入したり、新しいファイルを作成したりすることができます。特定の状況下では、攻撃者は同じLANに接続している開発者のマシン上でコードを実行することができます。

## 影響を受けるユーザー

以下のいずれかに該当する場合、影響を受ける可能性があります。
- 信頼できないローカルネットワークに接続している状態でStorybookの開発サーバーを実行している。
- 信頼されたネットワークを装ったWi-Fiアクセスポイントに接続している状態でStorybookの開発サーバーを実行している。
- Vitestアドオンをインストールしており、古いバージョンのVitestを使用している。

以下の場合は影響を受けません。
- ネットワーク上の他のデバイスからアクセスできない環境で開発サーバーを実行している(例:Storybookのポートを公開していないコンテナ、または`127.0.0.1`のみに公開しているコンテナ)。
- 信頼できるローカルネットワークに接続している状態で開発サーバーを実行している。
- 構築済みのStorybookを自分のマシンで提供している。

## 推奨される対応

### Storybookのアップデート

Storybookは、上記のような最悪のシナリオが発生する可能性のある脆弱性を修正した、影響を受けるすべての主要なStorybookバージョンに対して、修正版をリリースしました。

`storybook dev`を再度実行する前に、以下の修正版にアップデートしてください。すぐにアップデートできない場合は、修正を適用できるまで、影響を受けるStorybookの開発サーバーを実行しないでください。

- 11.0.0-alpha.6
- 10.6.2
- 9.1.21
- 8.6.19

### 互換性のない変更点の確認

報告された脆弱性の特異性から、Storybookチームは、Storybookのデフォルトの動作を、ほとんどのStorybookユーザーのワークフローに必須ではない、いくつかのネットワーク関連機能について変更することを決定しました。影響を受ける機能にチームが依存している場合は、このドキュメントに、以前の動作に戻す方法が説明されています。

#### Storybookはデフォルトで`127.0.0.1`のみを対象とするようになりました

デフォルトでは、Storybookの開発サーバーは、お客様のコンピューター上のすべてのネットワークインターフェースではなく、ループバックアドレス`127.0.0.1`のみを対象とします。`http://localhost:6006`でアクセスすることは引き続き可能です。これにより、同じネットワーク上の他のデバイスからStorybookサーバーが参照されるのを防ぎます。

Storybookを他のユーザーと共有するには、Chromatic(無料)に公開することを検討してください。開発サーバーを公開せずにLANで共有するには、`storybook build`で静的なStorybookを構築し、静的ファイルサーバーを使用して出力フォルダを提供します。

開発モードで動作しているStorybookを共有するには、`--host`というコマンドラインオプションを使用して、Storybookを共有するLANのIPアドレスを指定できます。例えば、`storybook dev --host 192.168.0.110`のように指定します。このオプションを使用すると、ホストとオリジンの検証は引き続き有効になります。代わりに`--host 0.0.0.0`を使用する場合は、使用するホスト名を`core.allowedHosts`に設定する必要があります。設定しない場合、ホストとオリジンの検証が無効になり、Storybookは警告を表示し、起動前に確認を求めます。

ファイアウォールを使用して、受信パケットを既知の同僚のIPアドレスに制限し、信頼できないWi-Fiネットワークでは`--host`オプションの使用を避けてください。

#### Vitestアドオンは、`browser.api.allowWrite`と`browser.api.allowExec`を無効にしました

Storybookでは、Vitestブラウザモードで実行されるコードが、開発者のコンピューターに書き込んだり、他のプロセスを実行したりすることができなくなりました。テストでこれらの機能に依存している可能性は低いですが、Vitestの設定でこれらのAPIを手動で再度有効にすることができます。

#### `saveStoryRequest`イベントにおける入力検証がより厳格になりました

Storybookは、`saveStoryRequest`における入力検証を強化しました。これにより、アドオンやStorybookのUIは、シリアル化された引数とストーリーのタイトルのみを書き込むことができるようになりました。入力検証の脆弱性を悪用して、例えば、カスタムアドオンで`play`関数を書き込むことはできなくなりました。

ユーザーの代わりにファイルを作成または編集するアドオンを開発する場合は、セキュリティに関するベストプラクティスについてアドバイスを受けるために、Storybookチームにお問い合わせください。

## 脆弱性公開の経緯

8月19日、Storybookチームは、攻撃者がStorybookの開発サーバーと同じLANに接続している場合、WebSocketのトークンを盗むことができるという、責任ある情報開示を受け取りました。

この情報開示では、攻撃者が実行できるいくつかの操作が特定されました。攻撃者は、入力検証を回避して、ストーリーファイルに悪意のあるコードを書き込むことができます。

その後、WebSocket経由でテストを実行させることができます。Vitestアドオンがインストールされている場合、その悪意のあるコードは、VitestのAPIを悪用して、ユーザーのファイルシステムに他のファイルを書き込む可能性があります。

悪意のあるコードの内容、書き込まれるファイルの場所、および開発者が使用するソフトウェアによっては、その攻撃が実行される可能性があります。

影響を受けるパッケージ:
- npm (JavaScript) storybook: 影響を受けるバージョン >= 8.0.0、< 8.6.19、8.6.19で修正済み
- npm (JavaScript) storybook: 影響を受けるバージョン >= 9.0.0、< 9.1.21、9.1.21で修正済み
- npm (JavaScript) storybook: 影響を受けるバージョン >= 10.0.0、< 10.6.2、10.6.2で修正済み
- npm (JavaScript) storybook: 影響を受けるバージョン >= 11.0.0-alpha.0、< 11.0.0-alpha.6、11.0.0-alpha.6で修正済み
- npm (JavaScript) @storybook/core: 影響を受けるバージョン >= 8.0.0、< 8.6.19、8.6.19で修正済み
- npm (JavaScript) @storybook/core-server: 影響を受けるバージョン >= 8.0.0、< 8.6.19、8.6.19で修正済み
- npm (JavaScript) @storybook/experimental-addon-test: 影響を受けるバージョン >= 8.0.0、< 8.6.19、8.6.19で修正済み
- npm (JavaScript) @storybook/addon-vitest: 影響を受けるバージョン >= 9.0.0、< 9.1.21、9.1.21で修正済み
- npm (JavaScript) @storybook/addon-vitest: 影響を受けるバージョン >= 10.0.0、< 10.6.2、10.6.2で修正済み
- npm (JavaScript) @storybook/addon-vitest: 影響を受けるバージョン >= 11.0.0-alpha.0、< 11.0.0-alpha.6、11.0.0-alpha.6で修正済み
- npm (JavaScript) @storybook/addon-mcp: 影響を受けるバージョン >= 10.6.0、< 10.6.2、10.6.2で修正済み
- npm (JavaScript) @storybook/addon-mcp: 影響を受けるバージョン >= 11.0.0-alpha.0、< 11.0.0-alpha.6、11.0.0-alpha.6で修正済み