Modern Frontend CVEs

対象CVE: CVE-2026-71320

[高深刻度RCE] Nuxt Server Islandにおけるランタイムテンプレートインジェクションの脆弱性について

NuxtのServer Island機能において、特定の条件下で攻撃者が任意のコードをサーバー側で実行できる高深刻度の脆弱性が発見されました。日本のフロントエンドエンジニアの皆さんは速やかに対応を確認してください。

はじめに

Nuxtアプリケーション開発者の皆さん、重要なセキュリティ情報です。NuxtのServer Island機能に、高深刻度(High Severity)のリモートコード実行(RCE)を可能にする脆弱性(GHSA-9473-5f9j-94wq / CVE-2026-71320)が報告されました。この脆弱性は、特定の条件下で攻撃者がNuxtサーバープロセス上で任意のコードを実行できてしまう可能性があります。この記事では、脆弱性の詳細、影響を受ける条件、そして対応策について、日本のフロントエンドエンジニア向けに分かりやすく解説します。

脆弱性の概要:Nuxt Server Islandのテンプレートインジェクション

この脆弱性は、NuxtのServer Island機能が`/__nuxt_island/`エンドポイント経由でプロップスを受け取る際に発生します。具体的には、攻撃者がプロップスに悪意のある`template`キーを注入できてしまうというものです。

もし`vue.runtimeCompiler: true`が有効な場合(デフォルトでは`false`)、注入された`template`の内容がVueのランタイムテンプレートコンパイラによってサーバープロセス内でコンパイル・実行されてしまいます。これにより、Nuxtサーバー上で任意のコードを実行するサーバーサイドのリモートコード実行(RCE)が可能となります。

脆弱性の発生条件と影響

この脆弱性が実際に悪用されるには、以下の**2つの主要な条件**が同時に満たされる必要があります。

1. **`vue.runtimeCompiler: true` が有効であること**

Nuxtではデフォルトで`vue.runtimeCompiler: false`に設定されています。したがって、ほとんどのNuxtアプリケーションはこの条件を満たさないため、影響を受けません。しかし、明示的に`true`に設定している場合は注意が必要です。

2. **Server Islandが動的コンポーネント解決にプロップスを渡していること**

アプリケーション内に、攻撃者から制御可能な値をVueの動的コンポーネント解決(例: `<component :is>`, `resolveDynamicComponent`, `h()`、または`@nuxt/ui`などのライブラリが提供する`as`/`asChild`プロップスなど)に渡しているServer Islandコンポーネントが存在する場合に、この条件が満たされます。

重要な点として、開発者が明示的にプロップスを転送していなくても、アイランドコンポーネントのルート要素が多態的なプロップス(`as` / `asChild`など)を受け入れる場合、未宣言のアイランドプロップスが属性としてフォールスルーする(標準のVue属性継承)ため、脆弱性が発生する可能性があります。例えば、`@nuxt/ui`の`UButton`をルートに持つシンプルなServer Islandでも、この経路で脆弱になる可能性があります。

例:以下のようなServer Islandは、`as`プロップスがフォールスルーする可能性があり、注意が必要です。

```vue\n<!-- components/MyWidget.server.vue -->\n<template>\n <UButton>Save</UButton>\n</template>\n```

これらの条件が満たされると、攻撃者は`/__nuxt_island/`エンドポイントに対して特別なJSONペイロード(例: `{"as": {"template": "<attacker-controlled>"}}`)を送信することで、Nuxtサーバープロセス上で任意のJavaScriptコードを実行できてしまいます。これは極めて危険な状態です。

影響を受けるNuxtのバージョン

この脆弱性の影響を受けるのは以下のNuxtバージョンです。

- Nuxt `>=3.4.0` から `<3.21.10`

- Nuxt `>=4.0.0` から `<4.5.1`

また、これらのバージョンであっても、`vue.runtimeCompiler: true`が有効であり、かつServer Islandが使用されている場合にのみ影響を受けます。Nuxt 2系はServer Island機能がないため影響を受けません。

対応策:すぐにアップグレードを!

最も推奨される対応策は、**Nuxtを修正済みバージョンにアップグレードすること**です。

- Nuxt `4.x`系をご利用の場合: `nuxt@4.5.1` 以上にアップグレード

- Nuxt `3.x`系をご利用の場合: `nuxt@3.21.10` 以上にアップグレード

修正済みバージョンでは、`vue.runtimeCompiler`が有効な場合、デコードされたプロップスに`template`キーが含まれているリクエストをHTTP 400エラーで拒否するガードが実装されています。これにより、不正なテンプレートインジェクションを防ぎます。

アップグレードが困難な場合の回避策

すぐにアップグレードできない場合でも、以下の回避策を適用することでリスクを軽減できます。

1. **`vue.runtimeCompiler` を `false` に設定する**

これが最も効果的な回避策です。アプリケーションの設定で`vue.runtimeCompiler: false`になっていることを確認してください。デフォルト設定であれば、この脆弱性の主要な前提条件を満たしません。

2. **動的コンポーネント解決へのプロップス転送を制限する**

Server Islandコンポーネント内で、攻撃者から渡される可能性のあるプロップスを、`<component :is>`, `resolveDynamicComponent`, `h()`、またはポリモーフィックな`as`/`asChild`プロップスに直接渡さないようにコードを見直してください。もし渡す必要がある場合は、厳密なサニタイズ処理を実装してください。

3. **WAF (Web Application Firewall) を導入する(防御的措置)**

WAFを導入し、`/__nuxt_island/`パスへのリクエストにおいて、URLデコードおよびJSONパースされたプロップス値に`template`または`render`という名前のプロパティが含まれている場合に、そのリクエストをブロックするルールを設定します。ただし、この方法はエッジレベルでの防御に過ぎず、SSR内部のアイランドレンダリングには適用されないため、完全な解決策ではないことに注意してください。

まとめ

このNuxtの脆弱性は、特定の限定的な条件下でリモートコード実行という深刻な影響をもたらす可能性があります。特に、開発環境や本番環境で`vue.runtimeCompiler: true`を設定しているアプリケーションは、速やかに対応状況を確認し、アップグレードまたは回避策を適用することが強く推奨されます。

フロントエンド開発においても、依存ライブラリの脆弱性情報には常にアンテナを張り、迅速な対応を心がけましょう。

← ブログ一覧に戻る