[react] CVE-2025-55182に対応しようねという警告と複数リポジトリから当てはまるものを洗い出すスクリプトを共有します

2025/12/27

react

こんにちは。

今回はCVE-2025-55182に対応しようねという警告と複数リポジトリから当てはまるものを洗い出すスクリプトを共有します。

CVE-2025-55182とは

React Server Components (RSC) における重大なリモートコード実行 (RCE) の脆弱性です。
CVSSスコアは最高の10.0が割り当てられています。
認証なしで攻撃者がサーバー上で任意のコードを実行できる可能性があります。
"React2Shell" とも呼ばれています。

対象になるパッケージとバージョン

以下のパッケージのバージョン 19.0, 19.1.0, 19.1.1, 19.2.0 が影響を受けます。

  • react-server-dom-webpack
  • react-server-dom-parcel
  • react-server-dom-turbopack

修正されたバージョン 19.0.1, 19.1.2, 19.2.1 へのアップグレードが推奨されます。
Next.js などのフレームワークを使用している場合も、対応するパッチバージョンへの更新が必要です。

スクリプト

以下のようなscan-packages.jsを作成し、実行しました。

scan-packages.js
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");

const ROOT = process.argv[2] ? path.resolve(process.argv[2]) : process.cwd();

// 今回特に見たいパッケージ
const TARGETS = [
  "react-server-dom-webpack",
  "react-server-dom-parcel",
  "react-server-dom-turbopack",
  "next",
];

function walk(dir, results = []) {
  const entries = fs.readdirSync(dir, { withFileTypes: true });
  for (const entry of entries) {
    // node_modules や .git などはスキップ
    if (["node_modules", ".git", ".next"].includes(entry.name)) continue;

    const full = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      walk(full, results);
    } else if (entry.isFile() && entry.name === "package.json") {
      results.push(full);
    }
  }
  return results;
}

function loadJson(file) {
  try {
    return JSON.parse(fs.readFileSync(file, "utf8"));
  } catch (e) {
    return null;
  }
}

function collect() {
  const files = walk(ROOT);
  const hits = [];

  for (const file of files) {
    const pkg = loadJson(file);
    if (!pkg) continue;

    const deps = {
      ...(pkg.dependencies || {}),
      ...(pkg.devDependencies || {}),
      ...(pkg.peerDependencies || {}),
    };

    const used = {};
    for (const name of TARGETS) {
      if (deps[name]) {
        used[name] = deps[name];
      }
    }

    if (Object.keys(used).length > 0) {
      hits.push({ file, used });
    }
  }
  return hits;
}

const hits = collect();
if (hits.length === 0) {
  console.log("No target packages found.");
  process.exit(0);
}

for (const hit of hits) {
  console.log("=== " + hit.file + " ===");
  for (const [name, version] of Object.entries(hit.used)) {
    console.log(`  ${name}: ${version}`);
  }
  console.log();
}

実行例

このスクリプトに実行権限を付与して実行するか、node コマンドで実行します。
引数として対象のディレクトリパスを渡すことができます(省略するとカレントディレクトリが対象になります)。

$ node scan-packages.js /path/to/your/projects

実行すると、以下のように対象パッケージが使用されている package.json のパスと、そのバージョンが表示されます。

=== /path/to/your/projects/app-A/package.json ===
  next: 15.0.3

=== /path/to/your/projects/repo-B/packages/web/package.json ===
  react-server-dom-webpack: 19.0.0

何も見つからなかった場合は No target packages found. と表示されます。