Next.js・RSCの脆弱性|同梱の修正を目印で確かめる


Next.jsとReact Server Components(RSC)の脆弱性の確認とは、公告が示す修正版より古いnextやreact-server-dom-*を見つけて上げ、上げたあとに本番で動くファイルに修正が入っていることまで確かめる作業です。Next.jsはRSCを自分の中に持っているので、npm ls react-server-dom-webpack では何も出てきません。判定はnextの版で行い、確認は修正で足された文字列を目印に探します。

2026年10月から11月にかけて、RSCの未認証のリモートコード実行(GHSA-xqc2-xf4c-x3h3)と、Next.jsの重大な公告が続けて出ました。Reactの公告は react-server-dom-webpack などのパッケージ名で修正版を示していますが、Next.jsのプロジェクトのlockfileにはそのパッケージが現れません。さらに、Next.jsの中のReactの版の表記は修正の前と後で同じでした。版の文字列だけを見て「直った」「直っていない」を決めると、判断を誤ります。

この記事では、公告の中身と修正版、自分のアプリが対象かの見分け方、npm ls・npm audit で見えるものと見えないもの、同梱のRSCに修正が入ったかを確かめるスクリプト、15系で残りやすいsharpの古い版、本番の出力(standalone)での確かめ方を、実測つきでまとめます。数字とコマンドは2026年11月12日に、macOS(Apple Silicon)・Node.js 23.10.0・npm 10.9.2で、npmに公開されているnextとreact-server-dom-webpackのパッケージを取り寄せて確かめました。公告の内容はGitHub Advisory Databaseの各公告とnpmの公開日で同じ日に確認しています。


結論:nextの版で判定し、目印の文字列とsharpの版で確かめる

Next.jsを使っているなら、判定の基準はnextの版です。16系は16.4.1以上、15系は15.5.28以上が、2026年10月の一括の修正を含む版です。そのうえで、次の3つを確かめれば作業が閉じます。

  1. 版を見る:npm ls next で実際に入っている版を出し、16.4.1以上か15.5.28以上かを見る(package.json の指定ではなくlockfileで解決された版)
  2. 目印を探す:node_modules/next/dist/compiled の中に、RSCの修正で足された文字列 Cannot transport a detached buffer があるかを数える。修正前の16.4.0・15.5.27は0件、修正後の16.4.1は44ファイル・15.5.28は40ファイルだった
  3. sharpを見る:画像の最適化を使い(公告の題はSVGファイルを使うとき)、glibcのLinuxで動かしているなら、npm ls sharp が0.35.5以上かを見る。15系はnextを上げても古いsharpが残ることがある

Next.jsを使わずにRSCを直接使っている構成(react-server-dom-webpack・-parcel・-turbopack を依存に書いているもの)は、Reactの公告の修正版(19.0.9・19.1.10・19.2.9・19.3.1)がそのまま基準になります。こちらは npm audit が公告を直接指して知らせてくれます。


2026年10〜11月に出た公告と修正版

対象の公告は次のとおりです。日付はGitHub Advisory Databaseへの掲載日(日本時間)で、修正版そのものはそれより前にnpmへ公開されていました(Reactの修正版とnext 16.4.1・15.5.28は、どれも日本時間の2026年10月15日にnpmへ公開)。

公告内容(公告の条件)対象の版修正版
GHSA-xqc2-xf4c-x3h3RSCの未認証のリモートコード実行。複数のtyped array(Uint8Arrayなど)と攻撃者が操れる値を応答で運ぶ、ごくまれな場合に起きる(critical・11月11日掲載)react-server-dom-webpack/-parcel/-turbopack の 19.0.0〜19.0.8・19.1.0〜19.1.9・19.2.0〜19.2.8・19.3.019.0.9・19.1.10・19.2.9・19.3.1
GHSA-673q-mjm6-r5xrApp RouterでCache Componentsを使い、'use cache' の関数が複数のtyped arrayを返すときのリモートコード実行(critical・10月23日掲載)next 16.0.0〜16.4.016.4.1
GHSA-2464-fhr4-w9xw画像の最適化(Image Optimization)でSVGファイルを使うとき(公告の題)。上流のライブラリのメモリの問題で、glibcのLinuxで動くときにリモートコード実行のおそれ(critical・10月23日掲載)next 10.0.0〜15.5.27・16.0.0〜16.4.015.5.28・16.4.1(回避策はsharpを0.35.5以上にする)
GHSA-p3m5-59mp-jv5rApp RouterでServer Actionsを1つ以上使うアプリに、細工したリクエストでCPUを使い切らせるサービス妨害(high・10月23日掲載)next 13.0.0〜15.5.27・16.0.0〜16.4.015.5.28・16.4.1
GHSA-h694-7cp9-m8p3cacheComponents: true で入れ子の 'use cache' がroot paramを読むと、別の値の内容を返すことがある(medium・10月23日掲載)next 16.3.0〜16.3.716.3.8

条件を細かく読み込むより、修正版へ上げる作業を先に始めるほうが早く終わります。GHSA-673q-mjm6-r5xrは「似た関数が無いアプリでもすぐに上げるべき」と書いており、回避策はありません。ほかの公告は条件を書いていて、たとえばGHSA-p3m5-59mp-jv5rはPages RouterだけのアプリとServer Actionsを使わないアプリを対象外としています。2026年11月12日の時点で、それぞれの系列の最新はnext 16.4.6・15.5.29で、どちらにも同じ修正の文字列が入っていることを確かめました(16.4.6は44ファイル・15.5.29は40ファイル)。


自分のアプリが対象かを見分ける

まず、どの構成に当たるかを決めます。見る場所が構成ごとに違うためです。

構成Reactの公告(RSC)Next.jsの公告判定に使う版
Next.js 16系(App Router)Next.jsの公告(GHSA-673q)として対象。16.4.1で同じ修正の文字列が足された(目印44ファイル・実測)対象next 16.4.1以上
Next.js 15系公告に記載なし。ただし15.5.28で同じ修正の文字列が足された(目印40ファイル・実測)対象(16系だけの公告を除く)next 15.5.28以上
Next.js 14系以前中のReactは18.3.0-canary(14.2.35で確認)。公告が示す対象の版(19系)の書き方には当たらないGHSA-2464(10.0.0から)・GHSA-p3m5(13.0.0から)の対象。14系の修正版は公告に無い15.5.28以上へ移る(それまではsharpを0.35.5以上に)
RSCを直接使う構成(react-server-dom-* を依存に書いている)対象関係なしreact-server-dom-* の修正版
サーバーを使わないReact(ViteのSPAなど)対象外(公告に「サーバーを使わないアプリは影響を受けない」とある)関係なし—

Pages Routerだけを使うNext.jsのアプリは、GHSA-p3m5-59mp-jv5rの公告では「対象外」と書かれています。ただし画像の最適化の公告(GHSA-2464-fhr4-w9xw)はルーターの種類を条件にしていないので、Pages Routerでも版を上げる理由は残ります。実行環境のNode.js自体の版は別の作業なので、Node.jsの脆弱性の確認と対応の手順で洗い出してください。


npm lsとnpm auditで見えるもの・見えないもの

次の3つのlockfileを作り、npm ls と npm audit の結果を比べました(npm install --package-lock-only --ignore-scripts で作成。2026年11月12日・npm 10.9.2)。

lockfileの中身npm ls react-server-dom-webpacknpm audit の結果
next 16.4.0何も出ない(empty)critical 1件。nextに対してGHSA-2464・GHSA-p3m5・GHSA-673qの3つを指す。Reactの公告GHSA-xqc2は出ない
next 16.4.1何も出ない(empty)0件
react-server-dom-webpack 19.3.0(直接の依存)react-server-dom-webpack@19.3.0critical 1件。GHSA-xqc2-xf4c-x3h3(19.3.0以上19.3.1未満)を指す

Next.jsのプロジェクトで、Reactの公告に書かれたパッケージ名を npm ls や lockfile のgrepで探しても、何も見つかりません。Next.jsはRSCを node_modules/next/dist/compiled/react-server-dom-webpack などに自分で持っていて、その package.json の名前は react-server-dom-webpack-builtin になっています。依存の木には現れないので、「見つからない=影響なし」と読むと誤ります。

npm audit はNext.js自身の公告でnextを指すので、Next.jsのプロジェクトでも何かが出ること自体は分かります。ただし出てくるのはNext.jsの公告の番号で、Reactの公告の番号ではありません。社内の連絡で「GHSA-xqc2-xf4c-x3h3が出ていない」ことを根拠にしないでください。


同梱のRSCに修正が入ったかを目印の文字列で確かめる

Next.jsの中のReactの版の表記は、修正の前と後で同じでした。npmから取り寄せたnextのパッケージで dist/compiled/react/cjs/react.production.js の版を見ると、次のとおりです。

next中のReactの版の表記目印のあるファイル
16.4.019.3.0-canary-278794d7-202610020
16.4.119.3.0-canary-278794d7-20261002(同じ)44
15.5.2719.2.0-canary-0bdb9206-202508180
15.5.2819.2.0-canary-0bdb9206-20250818(同じ)40

16.4.0と16.4.1の react-server-dom-webpack のファイルを比べると、中身は変わっていて、送るデータの塊が「切り離された(detached)バッファ」になっていたら止める処理と、そのエラーの文 Cannot transport a detached buffer. が足されていました。この文を目印にすると、版の表記に頼らずに修正の有無を数えられます。単体のパッケージでも同じで、react-server-dom-webpack 19.3.0・19.2.8は0ファイル、19.3.1は5ファイル・19.2.9は6ファイルでした。

目印は公式が示した確かめ方ではなく、今回の修正で足された文字列を使った方法です。判定の基準はあくまで版で、目印は「上げたつもりのものが、実際のファイルに入っているか」を確かめるために使います。次の修正でエラーの文が変わることもあるので、別の公告にはそのまま使わないでください。

プロジェクトのフォルダか、本番に置くフォルダを渡すと、nextとreact-server-dom-*の版と、目印のあるファイルの数を出すスクリプトです。.next/standalone があればそちらも数えます。

#!/bin/sh
set -u
dir="${1:-.}"
marker="Cannot transport a detached buffer"
ver() { node -p "require(require('path').resolve(process.argv[1])).version" "$1"; }
found=0
for pkg in next react-server-dom-webpack react-server-dom-turbopack react-server-dom-parcel; do
  pj="$dir/node_modules/$pkg/package.json"
  [ -f "$pj" ] || continue
  found=1
  hits=$(grep -rl "$marker" "$dir/node_modules/$pkg/" 2>/dev/null | wc -l | tr -d ' ')
  echo "$pkg $(ver "$pj") 目印のあるファイル: $hits"
done
sa="$dir/.next/standalone/node_modules/next"
if [ -f "$sa/package.json" ]; then
  found=1
  hits=$(grep -rl "$marker" "$sa/" 2>/dev/null | wc -l | tr -d ' ')
  echo "standalone の next $(ver "$sa/package.json") 目印のあるファイル: $hits"
fi
[ "$found" = 1 ] || echo "$dir に next と react-server-dom-* が見つかりません"

grepに渡す場所の末尾に / を付けているのは、pnpmのように node_modules/next がリンクになっている場合でも中をたどるためです(pnpmと同じリンクの形にしたフォルダで、15.5.28が40ファイルになることを確かめました)。渡したフォルダにnextもreact-server-dom-*も無いときは、そのことを1行出します。

16.4.1でビルドしたプロジェクトで動かした結果です(sh check-rsc-fix.sh .)。16.4.0で同じことをすると、どちらも0になりました。

next 16.4.1 目印のあるファイル: 44
standalone の next 16.4.1 目印のあるファイル: 2

合否の基準は「nextが16.4.1以上(15系なら15.5.28以上)で、目印のあるファイルが1以上」です。版は新しいのに目印が0なら、別の場所のnode_modulesを見ているか、ビルドの方式で読む場所が違うので、本番で動いているフォルダを渡して数え直します。


上げ方:16系・15系・14系以前

上げ方は系列で変わります。どれも、上げたあとに前の節のスクリプトで確かめるところまでを1回の作業にします。

16系:同じ系列の最新へ

npm install next@16.4.6
npm ls next sharp

16.4.1は sharp の範囲を ^0.35.5 にしています。sharp 0.35.4が入ったlockfileでnextを16.4.0から16.4.1へ上げると、sharpも0.35.5へ上がりました。

15系:nextを上げたあとにsharpを上げる

npm install next@15.5.29
npm ls sharp
npm update sharp
npm ls sharp

15系は、nextを上げてもsharpが古いまま残ることがあります。15.5.28が求めるsharpの範囲は ^0.34.3 || ^0.35.5 で、0.34系も許しているためです。sharp 0.34.5が入ったlockfileでnextを15.5.27から15.5.28へ上げると、sharpは0.34.5のままでした。このとき npm audit は、sharpに対して別の公告を3件(libvips・libheif・librsvg由来。いちばん新しい条件は0.35.5未満)highで出しました。npm update sharp を実行すると0.35.5になり、sharpの3件は消えました。

GHSA-2464-fhr4-w9xwの回避策は「Next.jsが使うsharpを0.35.5以上にする」なので、15系ではnextの版とsharpの版の両方を見て初めて閉じます。なお15.5.28では、RSC・sharpとは別に、nextが依存するpostcssの公告が npm audit に残りました。

14系以前:15.5.28以上へ移る計画を立てる

2026年10月の公告の修正版の欄に14系はありません。npmの14系の最新は14.2.35(日本時間の2025年12月12日公開)のままです。14系は15系への移行が必要になるので、移行の作業の見積もりを先に出し、終わるまでの間はsharpを0.35.5以上にしておくことが公告の回避策に当たります。


本番で確かめる:ビルドの出力ではなくnode_modulesを見る

16.4.1の最小のApp Routerのアプリを output: "standalone" でビルドし、目印のあるファイルを場所ごとに数えました(Turbopackでのビルド)。

場所目印のあるファイル(16.4.1)目印のあるファイル(16.4.0)
node_modules/next/dist/compiled440
.next/server00
.next/standalone/node_modules/next2(compiled/next-server/app-page-turbo.runtime.prod.js と experimental 版)0

ビルドの出力(.next/server)には目印が入らないので、そこを探しても修正の有無は分かりません。目印は node_modules/next の中の、実行時に読まれるファイルに入っていました。standaloneで出す場合は、必要なファイルだけが .next/standalone/node_modules/next へ写されるので、そこで数えます。Dockerなどに載せている場合は、イメージやサーバーの中で、アプリを置いたフォルダを渡して同じスクリプトを動かします。

ファイルの名前はビルドの方式で変わることがあるので、特定のファイル名ではなく node_modules/next の全体を数えるのが確実です。上げたあとに本番で0のままなら、デプロイがキャッシュした古い node_modules を使っている可能性があるので、lockfileの更新が本番のビルドに届いているかを見直します。


つまずきやすい点と確認の一覧

今回の作業で、判断を誤りやすかった点をまとめます。

つまずき起きること確かめ方
Reactの公告のパッケージ名をlockfileで探すNext.jsのプロジェクトでは何も見つからず「影響なし」と誤るnextの版で判定する
中のReactの版の表記で判定する修正の前と後で同じ表記なので区別できない目印の文字列を数える
package.json の指定だけを見る^16.4.0 のような範囲だと、lockfileの版は古いままnpm ls next で解決された版を見る
15系でnextだけ上げるsharpが0.34系のまま残るnpm ls sharp → npm update sharp
.next/server で修正を探す修正後でも0件node_modules/next か .next/standalone/node_modules/next を数える

上げたあとは、ローカル・CI・本番の3か所で同じスクリプトを動かし、どこか1か所でも目印が0なら、その場所の node_modules が古いと考えて入れ直します。依存の入れ直しでinstallスクリプトが関わる場合の考え方はnpm 12のinstallスクリプト停止|壊れる依存と許可の決め方で整理しています。


よくある質問

Q. Next.jsのプロジェクトで npm ls react-server-dom-webpack が空でした。影響は無いですか?

空でも影響が無いとは言えません。Next.jsはRSCを自分の中に持っていて、依存の木には現れないためです。nextの版が16.4.1以上(15系なら15.5.28以上)かで判定してください。

Q. npm audit でGHSA-xqc2-xf4c-x3h3が出ません。上げなくてよいですか?

Next.jsのプロジェクトでは、npm auditはReactの公告ではなくNext.jsの公告の番号でnextを指します。nextが修正版より古ければNext.jsの公告が出るので、それに従って上げてください。

Q. nextを16.4.1に上げたのに、中のReactの版の表記が変わりません。直っていますか?

表記は修正の前と後で同じでした。16.4.1では目印の文字列 Cannot transport a detached buffer が44ファイルにあり、16.4.0では0でした。表記ではなく目印の有無で確かめてください。

Q. Pages Routerだけを使っています。上げる必要はありますか?

あります。Server Actionsの公告はPages Routerを対象外としていますが、画像の最適化の公告(GHSA-2464-fhr4-w9xw)はルーターの種類を条件にしていません。15.5.28以上か16.4.1以上へ上げてください。

Q. Next.js 14を使っています。14の修正版は出ますか?

2026年10月の公告の修正版の欄に14系はありません。15.5.28以上への移行を計画し、それまでの間はsharpを0.35.5以上にするのが公告の回避策です。

Q. Viteで作ったReactのSPAも対象ですか?

Reactの公告は、サーバーを使わないアプリと、RSCに対応したフレームワーク・バンドラーを使っていないアプリは影響を受けないとしています。ViteのSPAのようにブラウザだけで動く構成は対象外です。


次に読む

実行環境のNode.js自体の版の洗い出しはNode.jsの脆弱性の確認と対応|全環境の版を洗い出すにまとめています。Next.jsのApp Routerでサーバーとブラウザの処理の境目につまずいたときはNext.jsでlocalStorageがhydration errorになる原因と解決法が、Reactそのものの基本から押さえたいときはReact入門|何が作れるかとVite 1コマンドで動かす最初の一歩が入り口になります。


関連記事