[緊急注意] 9routerで認証なしRCE、Next.jsミドルウェアの落とし穴 (CVE-2026-46339)
はじめに:Next.jsを使っているあなたへ
皆さん、こんにちは。日本のフロントエンドエンジニアの皆さんにとって、Next.jsは日々の開発で欠かせないフレームワークとなっていることでしょう。しかし、その便利さの裏には、サーバーサイドの挙動やデプロイ環境におけるセキュリティリスクも潜んでいます。今回解説するのは、Next.jsを基盤とするアプリケーション「9router」で発見された、非常に危険な「認証なしリモートコード実行(RCE)」の脆弱性 (CVE-2026-46339, GHSA-fhh6-4qxv-rpqj) についてです。
この脆弱性は 'critical' な深刻度と評価されており、攻撃者はネットワーク経由で、一切の事前準備や認証なしに、9routerが動作しているサーバー上でOSコマンドを実行できてしまいます。これは、最悪の場合、データ漏洩、システム停止、さらにはサーバーの完全乗っ取りにつながる可能性があります。 Next.jsのミドルウェア設定が原因の一つであるため、フロントエンドを主戦場とする皆さんにも、その仕組みと対策を理解していただくことが極めて重要です。
脆弱性の概要:認証なしでOSコマンド実行の危険性
9routerに存在するこの脆弱性は、認証されていないユーザーがリモートから任意のOSコマンドを実行できるというものです。Next.jsのミドルウェアが特定のAPIルート(具体的には `/api/cli-tools/*` および `/api/mcp/*`)に対して認証チェックを適切に適用していなかったことが根本原因です。これにより、認証なしでこれらのAPIにアクセスし、システム上で悪意のあるコマンドを実行させることが可能になっています。
なぜNext.jsフロントエンドエンジニアも知るべきか?
「サーバーサイドの脆弱性だから自分には関係ない」と感じる方もいるかもしれません。しかし、この脆弱性はNext.jsのミドルウェアの挙動、特に `matcher` の設定不備に起因しています。Next.jsはフルスタックフレームワークであり、フロントエンド開発者がバックエンドのAPIルートやミドルウェアを扱うことも多々あります。自分たちが開発・運用するNext.jsアプリケーションでも、同様の認証不備やAPI設計の甘さがないか、この脆弱性を教訓として見直す必要があります。単なるUI/UXだけでなく、アプリケーション全体のセキュリティに目を向ける意識が求められています。
脆弱性の仕組みと攻撃の流れ
このRCE脆弱性は、主に以下の3つの要素が組み合わさることで発生します。
1. **ミドルウェアの認証対象ルート設定不備**: `src/proxy.js` 内のNext.jsミドルウェアは、`config.matcher` に指定されたルートにのみ認証チェックを適用します。しかし、`/api/cli-tools/*` や `/api/mcp/*` といった重要なAPIエンドポイントがこのリストに含まれていなかったため、認証が完全にスキップされていました。
2. **認証なしでのコマンド登録**: 認証なしでアクセス可能な `/api/cli-tools/cowork-settings` への `POST` リクエストが、リクエストボディ内の `customPlugins` オブジェクトに含まれる `command` と `args` フィールドを、何の検証もなしにサーバーのメモリ上に保存していました。具体的には `registerCustomPlugin` 関数が、攻撃者から送られた悪意のあるコマンドをそのまま登録してしまいます。
3. **認証なしでの保存コマンド実行**: これまた認証なしでアクセスできる `/api/mcp/[plugin]/sse` への `GET` リクエストがトリガーとなり、前述のステップで保存された悪意のある `command` と `args` が `spawn()` 関数によって実行されます。`spawn()` 自体はシェルを使わない安全な設定で呼び出されますが、攻撃者がコマンドパスと引数を完全に制御できるため、結果として任意のOSコマンドが実行されてしまいます。
攻撃者は、わずか2ステップでRCEを達成できます。
1. 攻撃者は認証なしで `/api/cli-tools/cowork-settings` に対して `POST` リクエストを送信し、実行させたいコマンド(例:リバースシェルを確立するコマンド)と引数を `customPlugins` として登録します。
2. 次に、認証なしで `/api/mcp/rev/sse` のようなSSEエンドポイントに対して `GET` リクエストを送信します。このリクエストにより、サーバー上で先ほど登録された悪意のあるコマンドが実行され、攻撃者の指定したIPアドレスにリバースシェルが確立される、といった具合です。
影響を受けるバージョンと潜在的な被害
9routerの **v0.4.30 から v0.4.33** までのすべてのバージョンが影響を受けます。この脆弱性は、v0.4.30でMCP stdio→SSEブリッジ機能が追加された際に導入されましたが、この新しいルートに対する認証チェックがミドルウェアに追加されなかったために発生したとされています。
このRCE脆弱性の影響は甚大です。攻撃者は以下の様なことが可能になります。
<ul><li>**機密情報の漏洩**: サーバーのファイルシステムに自由にアクセスし、APIキー、TLS秘密鍵、各種認証トークン、AWS認証情報など、あらゆる機密情報が窃取される可能性があります。特に、`~/.claude/settings.json`(Anthropicトークン)や `$DATA_DIR/db.sqlite`(9routerデータベース、保存されたAPIキー)などが狙われるでしょう。</li><li>**データの改ざん**: 任意のファイルを書き換えたり、`cron` や `systemd` を利用してシステムに永続的な変更を加えることが可能です。</li><li>**サービス停止**: 9routerのプロセスを強制終了させたり、リソースを枯渇させたりしてサービスを停止させることが可能です。</li><li>**内部ネットワークへの侵入**: テスト環境では `docker` グループのメンバーシップが確認されており、これによりDockerコンテナからのエスケープを経て、ホストOSのルート権限まで奪取される可能性があります。</li><li>**広範囲な攻撃**: リモートからの認証なし攻撃が可能であり、ネットワークアクセスがあれば誰でも実行できてしまいます。</li></ul>
フロントエンドエンジニアが実践できる対策
9routerの修正はベンダーが行いますが、皆さんのNext.jsプロジェクトで同様のリスクを避けるために、以下の推奨対策を参考にしてください。これらの対策は、多層防御の観点からも重要です。
1. **修正策1: Next.jsミドルウェアの認証対象ルートを拡張する(最低限の修正)**<br>Next.jsのミドルウェア (`src/proxy.js` など、`middleware.ts` / `middleware.js` に相当する部分) 内の `config.matcher` に、以下のルートを追加し、認証チェックの対象に含めます。<br>`['/api/cli-tools/:path*', '/api/mcp/:path*']`<br>これにより、認証されていないアクセスを初期段階で防ぐことができます。Next.jsミドルウェアの `matcher` はパスにマッチしないと実行されないため、漏れがないか定期的に見直しましょう。
2. **修正策2: コマンド登録関数での厳格な検証(多層防御)**<br>`src/lib/mcp/stdioSseBridge.js` ファイル内の `registerCustomPlugin` 関数に、実行を許可するコマンドをホワイトリスト形式で定義し、それ以外の不審なコマンドの登録を拒否するロジックを追加します。これは、仮にミドルウェアの認証が突破されても、不正なコマンドが実行されるのを防ぐための防御策です。
3. **修正策3: API境界での入力値サニタイズ(多層防御)**<br>`src/app/api/cli-tools/cowork-settings/route.js` ファイル内で、`customPlugins` の入力値を処理する際に以下のサニタイズ処理を追加します。<br><ul><li>`command` が許可されたコマンドのホワイトリストに含まれているかを確認します。</li><li>`name` フィールドを、英数字と一部の記号(アンダースコア、ハイフン)のみを許可するようにサニタイズします。</li><li>`args` フィールドの各要素が必ず文字列であることを保証し、予期せぬデータ型が混入しないようにします。</li></ul><br>これは、APIエンドポイントにおける入力値検証の基本であり、フロントエンドからのリクエストが常に信頼できるとは限らないという前提に立つ多層防御の考え方です。
まとめ:セキュリティは全員の責任
今回の9routerの脆弱性は、Next.jsのようなフルスタックフレームワークを使用する際に、フロントエンドとバックエンドの境界が曖昧になりがちな現代の開発において、セキュリティ意識を高く持つことの重要性を示しています。ミドルウェアの設定一つが、これほどの重大な脆弱性につながる可能性があるという事実を真摯に受け止める必要があります。
自分たちのNext.jsプロジェクトのミドルウェアの `matcher` 設定、APIエンドポイントの認証・認可ロジック、そして入力値のサニタイズ・検証が適切に行われているか、改めて見直す良い機会と捉えましょう。常に最新の情報をキャッチアップし、セキュアな開発を心がけることが、私たちフロントエンドエンジニアの責任でもあります。
この記事が、皆さんのセキュリティ意識向上の一助となれば幸いです。