2026年10月14日、Next.js 脆弱性が3件同時に公開されました。画像最適化 API が SVG を扱うときに認証なしのリモートコード実行(RCE)に至る CVE-2026-96889(GHSA-2464-fhr4-w9xw)、use cache 関数が型付き配列を返す構成での RCE(GHSA-673q-mjm6-r5xr)、Server Actions を使う App Router のサービス拒否(GHSA-p3m5-59mp-jv5r)です。修正版は 15.5.28 と 16.4.1。CVE-2026-96889 の原因は Next.js 本体ではなく、sharp が同梱する librsvg にあります。npm と pnpm では 15系の Next.js を上げても lockfile の sharp が古いまま残ることを再現できたので、その確かめ方までまとめます。
TIMELINE修正版が出るまで
上流の修正からNext.jsの修正版まで3週間
-
09.23
librsvg の解放後使用を修正
RUSTSEC-2026-0305(CVE-2026-96889)
-
09.27
sharp 0.35.5 を公開
librsvg 2.63.2 を同梱。新規インストールはここで解消
-
09.30
sharp がアドバイザリを公開
GHSA-wq5f-xc86-pv6w(0.35.5 未満が対象)
-
10.14
Next.js が3件を公開
critical 2件・high 1件。修正版は 15.5.28 と 16.4.1
30秒でわかる
- ・critical 2件・high 1件。修正版は 15.5.28(15系)と 16.4.1(16系)。14系以前に修正版は無い
- ・CVE-2026-96889 の本体は librsvg の解放後使用。sharp 0.35.5(librsvg 2.63.2 を同梱)以上なら塞がる
- ・15.5.28 は sharp 0.34 系も許すため、npm と pnpm では sharp 0.34.5 が lockfile に残った(実測)。
npm update sharpで上がる - ・
use cacheの RCE と Server Actions の DoS には回避策が無い。npm auditはこの2件を返さない(10月16日実測) - ・確認は
npm ls next sharpと、sharp のversions.rsvgが 2.63.2 以上か
依存の奥にある部品がそのまま攻撃面になる構図は サプライチェーン攻撃とは|手口・防御ツール比較・npm 12の新機構まで実践解説 で、2026年8月までの Next.js の脆弱性は Next.js脆弱性|CVE-2026-75604とAVIF RCEの影響範囲・自分のアプリの確認手順 で扱っています。
CVE-2026-96889 の時系列——上流の修正から Next.js 15.5.28/16.4.1 まで
時刻は npm レジストリの公開時刻を日本時間に直したもの、日付だけの行は各アドバイザリの表記です。
| 日時(日本時間) | 出来事 |
|---|---|
| 9月23日 | librsvg の解放後使用が RustSec に登録(RUSTSEC-2026-0305、別名 CVE-2026-96889) |
| 9月27日 21:11 | sharp-libvips 1.3.4 公開(librsvg を 2.62.91 から 2.63.2 へ) |
| 9月27日 22:46 | sharp 0.35.5 公開 |
| 9月30日 | sharp がアドバイザリ GHSA-wq5f-xc86-pv6w を公開(GitHub Advisory Database への反映は10月6日) |
| 10月7日 3:35 | next 16.4.0 公開(sharp の宣言は ^0.35.4 のまま) |
| 10月14日 | Next.js が3件のアドバイザリを公開 |
| 10月15日 2:36/2:43 | next 15.5.28/16.4.1 公開 |
| 10月16日 5:57 | next 16.4.2 公開(latest。アドバイザリの修正版の記載は 16.4.1) |
上流の修正から Next.js のアドバイザリまで3週間あり、その間に sharp 0.35.5 が出ています。9月27日以降に lockfile を新しく作ったプロジェクトは、Next.js が 16.4.0 のままでも sharp 0.35.5 を引いていました(--package-lock-only で [email protected] を解決して確認)。逆に、それより前に作った lockfile は、何かのきっかけで sharp が解決し直されない限り古い sharp を持ち続けます。
Next.js 側では9月22日に next/og の RCE(CVE-2026-94545、16.3.6 で修正)、9月30日に7件が公開されており、10月14日は1か月で3回目のセキュリティ公開です。5月の SSRF 単体の経緯は Next.js CVE-2026-44578|WebSocket SSRF(CVSS 8.6)の仕組みと緊急対策 にあります。
何が起きたか——Next.js 脆弱性3件の中身
| 項目 | CVE-2026-96889 | GHSA-673q-mjm6-r5xr | GHSA-p3m5-59mp-jv5r |
|---|---|---|---|
| 内容 | 画像最適化 API の SVG で RCE | use cache の型付き配列で RCE |
Server Actions で DoS |
| 深刻度 | critical(CVSS 4.0 で 9.5) | critical(9.5) | high(8.2) |
| CVE | CVE-2026-96889 | 未採番 | 未採番 |
| 対象 | 10.0.0〜15.5.27、16.0.0〜16.4.0 | 16.0.0〜16.4.0 | 13.0.0〜15.5.27、16.0.0〜16.4.0 |
| 修正版 | 15.5.28/16.4.1 | 16.4.1 | 15.5.28/16.4.1 |
| 回避策 | sharp を 0.35.5 以上に | なし | なし |
CVE-2026-96889 の16系の下限は、アドバイザリ上 > 16.0.0 と書かれています。16.0.0 自体を除く意図なのかは読み取れないので、16.0.0 も対象として扱うのが安全です。
CVE-2026-96889——原因は3段下の librsvg
DEPENDENCY CHAINSVG が届く先
原因は Next.js の3段下にある librsvg
-
next
画像最適化 API
-
sharp
0.35.5 で修正
-
libvips
画像処理の本体
-
librsvg
2.63.2 で修正
Next.js のアドバイザリは原因を「画像最適化が使う上流ライブラリのメモリ関連の脆弱性」とだけ書き、glibc 系の Linux で動かしているときに RCE の可能性があるとしています。上流を名指ししているのは sharp のアドバイザリ GHSA-wq5f-xc86-pv6w で、librsvg の CVE-2026-96889 を挙げ、sharp 0.35.5 で librsvg 2.63.2 になったとしています。
RustSec の記載によると、ネストした XInclude を含む SVG を読む途中で同じ名前の XML エンティティが再宣言されると、外側のパースがまだ使っているエンティティを librsvg 側が解放してしまう、という解放後使用です。修正済みは 2.63.2 以上で、旧系列にも 2.62.4・2.61.5・2.60.3・2.57.5 の修正版があります。sharp の同梱版は、0.34.5 が librsvg 2.61.2、0.35.4 が 2.62.91 で、どちらも修正済みの範囲に入りません。
配布物を比べると、next 16.4.0 と 16.4.1 で画像最適化のコード(image-optimizer.js と image-optimizer/ 配下)は1バイトも変わっておらず、package.json の sharp の宣言が ^0.35.4 から ^0.35.5 になっただけでした。つまり CVE-2026-96889 の修正の実体は sharp の版そのもので、Next.js を上げても sharp が古ければ何も変わりません。15.5.28 と 16.4.1 はどちらも sharp の SVG ローダー(VipsForeignLoadSvg)を許可リストに入れたままです。
sharp のアドバイザリは、sharp を直接使う人向けの回避策として SVG の読み込みを sharp.block() で止める方法と、PIE としてビルドした node を使う方法(公式の Node.js バイナリは PIE ではない)を挙げています。Next.js 経由の利用でこれらが効くかは当サイトでは検証しておらず、恒久策は sharp 0.35.5 以上です。
なお Next.js の画像最適化は、先頭バイトで SVG と判定できた画像を dangerouslyAllowSVG が無効なら拒否し、有効でも最適化せずに返す作りです。どの経路で librsvg に届くのかはアドバイザリに書かれておらず、dangerouslyAllowSVG を無効にしていれば防げるのかは未検証です。
use cache 関数の RCE(GHSA-673q-mjm6-r5xr)
App Router で Cache Components を使い、型付き配列を複数返す use cache 関数があると RCE に至るとされています。対象は16系だけで、既知の回避策は無く、アドバイザリは「同様の関数が無くても直ちに上げるべき」と書いています。16.4.0 と 16.4.1 の配布物の差分には同梱の react-server-dom-*(Server Components のシリアライザ)の変更が含まれますが、どの変更がこの件の修正かは切り分けていません。
Server Actions の DoS(GHSA-p3m5-59mp-jv5r)
Server Action を1つ以上持つ App Router のアプリに細工したリクエストを送ると、CPU を使い切って同じプロセスの後続リクエストを止められます。Pages Router だけのアプリと、Server Actions を使っていないアプリは対象外です。回避策は無く、2026年7月にも同じ題名の別件(GHSA-m99w-x7hq-7vfj)が出ています。
対策——安全なバージョンと、sharp を一緒に上げる手順
| 系列 | 修正版 | next が宣言する sharp | 注意 |
|---|---|---|---|
| 16系 | 16.4.1(latest は 16.4.2) | ^0.35.5 |
16.3系以前からは 16.4 へのマイナー移行になる |
| 15系 | 15.5.28(dist-tag は backport) | ^0.34.3 \|\| ^0.35.5 |
既存の lockfile の sharp 0.34 系が残る |
| 14系以前 | なし | 宣言なし(14.2.35 で確認) | 15.5.28 以上へ移行する |
| canary | アドバイザリに記載なし | ^0.35.4(16.5.0-canary.15) |
修正の有無は未検証。本番で使わない |
16系は ^0.35.5 しか許さないので、16.4.1 に上げると sharp も 0.35.5 へ解決し直されます(16.3.5 の lockfile から上げて確認)。問題は15系です。
LOCKFILE TRAP15系の落とし穴
next を上げてもsharp 0.34.5 が残る
npm で行った操作
lockfile の sharp
npm で行った操作: [email protected] で作った lockfile
lockfile の sharp: 0.34.5(librsvg 2.61.2)
npm で行った操作: npm install [email protected]
lockfile の sharp: 0.34.5 のまま
npm で行った操作: npm update sharp
lockfile の sharp: 0.35.5(librsvg 2.63.2)
15.5.28 は sharp 0.34 系も許すため、next 15.5.23 で作った lockfile から npm install [email protected] を実行しても sharp は 0.34.5 のままでした。pnpm 10.28.0 の pnpm add [email protected] でも同じで、yarn 1.22.22 だけは範囲の文字列が変わったことで 0.35.5 に解決し直しました。インストール後に require('sharp').versions を読むと librsvg は 2.61.2 で、修正前の版がそのまま動きます。
# 16系
npm install [email protected]
# 15系: next を上げたあと、sharp を宣言範囲の最新(0.35.5)へ上げる
npm install [email protected]
npm update sharp
# 反映を確かめる(sharp 0.35.5 以上、librsvg 2.63.2 以上)
npm ls next sharp
node -p "require('sharp').versions.rsvg"
npm update sharp で 0.35.5(librsvg 2.63.2)に上がり、package.json に sharp の直接依存は増えませんでした。pnpm では pnpm update sharp で lockfile の sharp が 0.35.5 になることを確認しています。
自システム確認コマンド——CVE-2026-96889 と残り2件を切り分ける
package.json の記載ではなく、lockfile と実際に入っている版を見ます。モノレポでは apps/web/ のような下位ディレクトリにも lockfile があるので、まずリポジトリ全体を探します。
git fetch --all --prune
# 1. リポジトリ内の lockfile をすべて探す(依存パッケージの中身は除く)
find . \( -name package-lock.json -o -name pnpm-lock.yaml -o -name yarn.lock \) -not -path '*/node_modules/*'
# 2. 見つかった lockfile のあるディレクトリで、実際に入る next と sharp の版を読む
grep -n -A1 -E 'node_modules/(next|sharp)":' package-lock.json
grep -n -E '^ /?(next|sharp)@[0-9]' pnpm-lock.yaml
grep -n -A1 -E '^"?(next|sharp)@' yarn.lock
# 3. インストール済みの環境で、sharp が同梱する librsvg の版(2.63.2 以上なら CVE-2026-96889 は塞がっている)
npm ls next sharp
node -p "require('sharp').versions.rsvg"
# 4. 本番ホストの C ライブラリ(GLIBC と出れば、アドバイザリが RCE の条件に挙げる glibc 系 Linux)
ldd --version 2>&1 | head -n 1
次に、3件それぞれの条件に当たるコードがあるかを見ます。
# Server Actions(GHSA-p3m5): 'use server' を書いたファイル
grep -rlE "^\s*['\"]use server['\"]" --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' --exclude-dir=node_modules --exclude-dir=.next .
# use cache(GHSA-673q): 'use cache' を書いたファイルと Cache Components の設定
grep -rlE "^\s*['\"]use cache" --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' --exclude-dir=node_modules --exclude-dir=.next .
grep -rnE "cacheComponents|useCache" --include='next.config.*' --exclude-dir=node_modules .
# 画像最適化(CVE-2026-96889): next/image の利用と、最適化を止める設定
grep -rlE "from ['\"]next/(image|legacy/image)['\"]" --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' --exclude-dir=node_modules --exclude-dir=.next .
grep -rnE "unoptimized|loader|dangerouslyAllowSVG|remotePatterns" --include='next.config.*' --exclude-dir=node_modules .
どちらも擬似プロジェクト2つで対照を取りました。陽性側(apps/web/ に sharp 0.34.5 の lockfile、'use server'・'use cache'・cacheComponents: true・next/image を置いたもの)では全項目が当たり、陰性側(Pages Router だけ・16.4.1 と sharp 0.35.5 の lockfile・unoptimized: true)では lockfile と設定の1行以外は0件でした。依存の中に置いたおとりの 'use server' と lockfile は、両方とも拾っていません。ldd は Ubuntu(glibc 2.39)で GLIBC と出ることを確認しましたが、musl(Alpine)での出力は未検証です。
'use server' が1件も無ければ GHSA-p3m5 は、'use cache' が無ければ GHSA-673q は当たりません。ただしどちらも回避策が無く、検索漏れのリスクもあるので、結果にかかわらず修正版へ上げてください。
影響範囲——CVE-2026-96889 と残り2件の条件、npm audit で見えるもの
| 条件 | CVE-2026-96889 | GHSA-673q(use cache) | GHSA-p3m5(Server Actions) |
|---|---|---|---|
| OS | glibc 系 Linux で RCE の可能性(アドバイザリ)。他の OS の扱いは記載なし | 記載なし | 記載なし |
| ルーター | 問わない | App Router + Cache Components | App Router のみ |
| 機能 | 画像最適化 API(/_next/image) |
型付き配列を複数返す use cache 関数 |
Server Action が1つ以上 |
| 塞ぐもの | sharp 0.35.5 以上 | 16.4.1 以上 | 15.5.28/16.4.1 以上 |
配布物の next-server.js を読むと、15.5.28 でも 16.4.1 でも、images.unoptimized: true か loader が既定以外のとき /_next/image は404を返して最適化に進みません。この構成なら CVE-2026-96889 の入口は閉じていると読めますが、起動しての確認はしていません。Vercel などのホスティング上での扱いは、アドバイザリに記載が無く当サイトでも確かめていません。
スキャナの見え方は10月16日9時台(日本時間)に測りました。
| 照会先 | 結果 | 対照 |
|---|---|---|
npm audit のデータ源(bulk API)に next 16.4.0 と 15.5.27 を照会 |
3件とも返らない(0件) | next 16.3.5 では9月公開分の7件が返る |
[email protected] を新しく解決した lockfile で npm audit |
0件(sharp は 0.35.5) | — |
sharp 0.35.4 が残る lockfile で npm audit |
sharp を high(GHSA-wq5f)として報告。next は出ない | — |
| GitHub Advisory Database(グローバル) | 3件とも404 | 9月22日の GHSA-vcvr-r3jv-pc5j は掲載 |
npm audit が CVE-2026-96889 に気づけるのは、sharp 側のアドバイザリ経由で、sharp が古いときだけです。use cache の RCE と Server Actions の DoS は、10月16日時点ではどの経路でも出てきません。スキャナが静かなことを安全の根拠にせず、npm ls next sharp の実際の版で判断してください。公開 PoC の有無は本記事では調べていません。
本記事の実測環境は Node.js 22.22.0、npm 10.9.4、pnpm 10.28.0、yarn 1.22.22、Ubuntu(glibc 2.39)で、すべて2026年10月16日に行いました。
参照ソース
・GHSA-2464-fhr4-w9xw — Unauthenticated Remote Code Execution in Image Optimization API when SVG files are used(CVE-2026-96889)
・GHSA-673q-mjm6-r5xr — Unauthenticated Remote Code Execution in use cache functions returning typed arrays
・GHSA-p3m5-59mp-jv5r — Denial of Service in App Router using Server Actions
・GHSA-wq5f-xc86-pv6w — sharp: Vulnerability in librsvg dependency CVE-2026-96889
・RUSTSEC-2026-0305 — librsvg: Use-after-free when XML includes have duplicated entities
・sharp-libvips v1.3.4(同梱ライブラリの版。librsvg 2.63.2)
・sharp v0.35.5 の変更履歴
・vercel/next.js Security Advisories 一覧(9月22日・9月30日公開分の確認元)





