Reactで最高スコアの脆弱性が出た

Blog

数日前、React Server Components(RSC)で重大なセキュリティ脆弱性があると報告されました。

https://forest.watch.impress.co.jp/docs/news/2068815.html
https://www.itmedia.co.jp/enterprise/articles/2512/06/news010.html

RSCのプロトコル実装にある問題が原因で、悪意あるリクエストを受け取ると、サーバー側で任意のコードが実行される可能性(RCE: Remote Code Execution)がある、というものです。

各メディアでも取り上げられていますが、Next.jsはApp routerにおいてRSCを利用しているため、Reactの脆弱性に巻き込まれた形です。

https://nextjs.org/blog/CVE-2025-66478

この脆弱性の深刻度は最高ランクの CVSS 10.0(Critical) とのこと。

CVSSとは脆弱性の深刻度を0.0~10.0の数値で表す国際的な指標で、高いほどリスクが高いことを意味します。

今回の10.0は近年稀にみる高スコアらしいです。

これを踏まえ、業務で利用しているNext.jsもバージョンアップを行いました。

上記の記事にもありますが、VercelのCLIツール(fix-react2shell-next)を使えばReactとNext.jsの安全な組み合わせに自動修正してくれるようです。


SemVerについて

ついでに、npmの~, ^とかのバージョン指定方法 ってどれがどれだっけ・・となったのでおさらいします。

前提として、npmは セマンティックバージョニング と言って3つの数字(例:1.2.3)に major , minor , patch という意味を持たせています。

major :前のバージョンと互換性を損なう変更をするときに上げる数字
minor :前のバージョンと互換性を持つ新機能追加の変更をするときに上げる数字
patch :前のバージョンと互換性を持つバグ修正の変更をするときに上げる数字

指定方法は以下の4つです。

  1. バージョンの数字のみの記載

範囲なしで固定のバージョンのみを許容します。

1.2.3:1.2.3のみ

  1. xまたは*

x*は「その桁をワイルドカード扱いにする」という意味になります。

1.x :1.0.0 以上、2.0.0 未満
1.2.x :1.2.0 以上、1.3.0 未満

  1. ~(チルダ)

前のバージョンとの互換性を保ちながら、patchの更新のみ最新バージョンを利用できます。
正確には、最後に明示した桁まで固定になります。

~1.2.3:1.2.3以上、1.3.0未満(patchのみ更新)
~1:1.0.0以上、2.0.0未満(major以外が更新される)

  1. ^(キャレット)

前のバージョンとの互換性を保ちながら、minor・patchの更新を最新バージョンまで利用できます。majorは固定。
0系では挙動が異なり、厳しく制限されます。

^1.2.3:1.2.3以上、2.0.0未満(1の変更は許容しない)
^0.0.3:0.0.3以上、0.0.4未満

npmはデフォルトでキャレット(^)が付く設定になっています。

他の指定方法が必要なのは、それぞれ以下のような場合かなと思います。実際にここまで考えて使ってはいません。😶‍🌫️

指定方法 利用ケース
固定バージョン(1.2.3 本番で絶対に同じ挙動にしたい / バグや互換性のリスクを徹底して避けたいとき。
チルダ(~1.2.3 パッチ更新のみ自動で取り込みたいとき。マイナーは固定されるので、リスクは固定バージョン以上、キャレット以下
x / *(1.x / * 互換性などの兼ね合いでバージョンを幅広く許可したいとき。不安定なので本番環境ではあまり使用されないのでは