TanStack Startは、Webアプリを作るためのフレームワーク(土台の部品)です。React・Solid・Vueのどれかで画面を書き、サーバーで動く処理も同じ場所に書けます。このTanStack Startに、ログインしていない外の人が仕掛けられるXSS(クロスサイトスクリプティング)の脆弱性(CVE-2026-102989)がありました。
深刻度を表すCVSS(3.1)は9.3(Critical)です。直した版は10月1日に出ています。GitHubの脆弱性データベースが確認済みとして載せたのは10月16日で、ここから開発部門にDependabot(使っている部品の脆弱性を知らせるGitHubの機能)の通知が届きます。日付は日本時間です。
TanStack Startで何が起きるか
TanStack Startには「サーバー関数」という仕組みがあります。画面の側から呼ぶと、サーバーで動く処理です。データベースの読み書きなどに使います。公式の文書は、アプリ自身から呼ぶための窓口と位置づけています。
告知によると、ログインしていない攻撃者が、サーバー関数を指すURLを細工できました。だれかがそのリンクを開くと、アプリは攻撃者の用意したHTMLを、自分のサイトのページとして返します。その結果、攻撃者のJavaScriptがアプリのサイトの中で動きます。
原因は、サーバー関数の受け渡しの処理です。外から送られた値が、内部の状態に入り込める作りでした。さらに、応答の形をした値を、そのままHTTPの応答として扱っていました。
GitHubのデータベースのTanStack Startの告知。対象の版と直した版、CVSS 9.3が並ぶ出典: GitHub(GitHub Advisory Database)(引用)
XSSで何をされるのか
告知は、動いたスクリプトにできることを次のように書いています。
The script can access same-origin data available to that visitor and make requests with their authority.
出典: TanStack「Unauthenticated reflected XSS in TanStack Start server-function responses」
リンクを開いた人に見えるそのサイトのデータを読め、その人の権限で要求を送れる、という意味です。たとえば社内の管理画面をTanStack Startで作っている場合、ログインした担当者がリンクを開くと、その担当者の権限で操作される恐れがあります(編集部の整理)。
CVSSの内訳では、攻撃の経路はネットワークで、必要な権限はなしです。ただし、リンクを開くという利用者の操作が要ります。機密性と完全性への影響は高とされています。
米国CISAが10月15日に付けた評価(SSVC)は、悪用は「なし」、自動化は「できない」、技術的な影響は「全体」です。
対象の版と直した版
| パッケージ(npm) |
対象 |
直した版 |
| @tanstack/react-start |
1.143.12以上、1.168.60より前 |
1.168.60 |
| @tanstack/solid-start |
1.143.12以上、1.168.57より前 |
1.168.57 |
| @tanstack/vue-start |
1.143.12以上、1.168.56より前 |
1.168.56 |
| @tanstack/start-server-core |
1.143.12以上、1.169.39より前 |
1.169.39 |
1.143.12は2025年12月27日の版です(npmの記録)。そこから9月末までの版が対象です。直した版は、協定世界時の9月30日17時47分の一括のリリースで出ました。日本時間では10月1日の未明です。
リリースノートには、修正が「start: align server function transport behavior (#8573)」として載っています。告知の参考の欄も、この変更を挙げています。
TanStackの9月30日(協定世界時)のリリース。修正#8573と直した版が並ぶ出典: TanStack(TanStack/router)(引用)
10月18日時点の最新は、react-start・solid-start・vue-startが1.169.3、start-server-coreが1.169.44です。告知は、古い系統向けの修正(バックポート)があれば使うよう書いています。ただ、npmの記録では、10月1日以降に古い系統の版は出ていません。
悪用について、告知とリリースノートに記載はありません。CISAのKEV(悪用が確認された脆弱性の一覧)には、10月16日版で載っていません。米国NVDは、まだ分析していない段階です。
版の確かめ方
調べるのは、アプリのソースコードの置き場(リポジトリ)です。開発部門や委託先に、次の3つを見てもらいます。
- package.jsonで、@tanstack/react-start・solid-start・vue-startのどれかを使っているかを見ます。
- lockfile(package-lock.json・pnpm-lock.yaml・yarn.lockなど、入れた版を固定する記録)で、@tanstack/start-server-coreの実際の版を見ます。
npm ls @tanstack/start-server-core(pnpmなら pnpm why @tanstack/start-server-core)で、入っている版をすべて出します。古い版が1つも残っていないかを確かめます。
react-startなどは、start-server-coreの版をぴったり指定しています(npmの記録)。そのため、react-startを直した版に上げれば、start-server-coreも直った版になります。package.jsonでstart-server-coreを別に指定している場合は、そちらも上げます。
上げたら、ビルドと本番への反映まで済ませます。本番で動いている版が変わったことも確かめます(編集部の補足)。
上げるまでのしのぎ方
告知には、仮の対策が書かれています。どれも完全な修正ではないと、告知自身が断っています。
| 仮の対策 |
中身 |
注意 |
| WAFや手前の中継で止める |
サーバー関数の通り道(ふつうは/_serverFn/*)で、x-tsr-serverFn: trueのヘッダーが無い要求と、ブラウザーがページとして開く要求を止める |
ヘッダーは送る側が自由に付けられ、認証にはならない |
| CSP(読み込み元の制限)を付ける |
サーバー関数の応答に、厳しいContent Security Policyを付ける |
ブラウザーの側での制限にとどまる |
「ページとして開く要求」は、告知ではSec-Fetch-Mode: navigateや、Accept: text/htmlの付いた要求を指します。告知は、正しいGETとPOSTのサーバー関数が止まらないか、試してから入れるよう求めています。
影響する会社・しない会社
- 影響する: TanStack Start(react-start・solid-start・vue-start)の1.143.12以降、直した版より前で作ったWebアプリを動かしている会社
- 影響する: とくに急ぐのは、社員や取引先がログインして使う管理画面や、会員のいるサービスをTanStack Startで作っている会社です
- 確認が要る: 開発会社や委託先に作ってもらったWebアプリがある会社。使っているフレームワークと版は、作った側に聞きます
- 影響しない: 直した版以降に上げて、本番に反映した会社
- 影響しない: 1.143.12より前の版を使っている会社。告知の対象外ですが、ふだんの更新の中で新しい版へ上げます
- 告知の対象に挙がっていない: TanStack Startを使わず、TanStack QueryやTanStack Routerだけを使う会社
情シスが今日やること
- TanStack Startを使うアプリを洗い出します。 開発部門と委託先に聞き、GitHubのDependabotの通知も見ます。リポジトリのpackage.jsonで、@tanstack/react-start・solid-start・vue-startを探します。
- 入っている版を確かめます。 lockfileと
npm ls @tanstack/start-server-core で、1.169.39より前が残っていないかを見ます。
- 直した版へ上げる日を決めます。 最新の1.169系か、少なくとも表の直した版にします。検証の環境でサーバー関数の動きを確かめてから、本番に出します。
- すぐに上げられないアプリには、しのぎ方を入れます。 WAFや手前の中継に告知のルールを入れ、正しい呼び出しが止まらないかを試してから広げます。
- 社内に一言知らせます。 直るまでの間、メールやチャットで届いた社内のアプリへのリンクは開かず、ブックマークから開くよう伝えます(編集部の補足)。
開発部門との役割の分け方は、開発者に管理者権限を渡す?開発部門と情シスが折り合う決め方でも扱っています。部品の脆弱性に追いつく更新の回し方は、AIが脆弱性を見つける時代の更新運用 OSS・SBOM・OT対策の進め方にまとめています。