React RCE 漏洞扫描工具 (CVE-2025-55182)

一个强大的安全扫描工具,旨在检测 React、Next.js 以及其他使用 React 服务器组件(RSC)的项目中的 CVE-2025-55182CVE-2025-66478 高危漏洞。

📋 项目概述

此工具可自动扫描您的项目,检查是否使用了存在**远程代码执行(RCE)**漏洞的 React、Next.js 及相关 RSC 包版本。攻击者可利用此漏洞在您的服务器上未经授权执行任意代码,风险极高。

⚠️ 紧急提醒: 截至 2025 年 12 月,约有 39% 的云环境 仍在使用存在漏洞的 Next.js 或 React 版本。如果您正在使用 React 服务器组件,请立即采取行动。

✨ 功能特性

  • 🔍 自动化依赖检测:深度扫描 node_modules,精准识别易受攻击的包版本。
  • 📁 项目架构分析:智能判断项目使用的是 Next.js 的 App Router 还是 Pages Router。
  • 🔎 服务器 Actions 扫描:在您的代码库中高效定位包含 "use server" 指令的文件。
  • 🛠️ RSC 框架识别:自动检测项目是否使用了支持 RSC 的框架(如 Remix、Waku、RedwoodJS 等)。
  • 📊 风险等级评估:根据扫描结果,给出清晰的风险结论(严重/中等/安全)。
  • 💡 修复指南:提供精确的升级命令和步骤,帮助您快速修复漏洞。

📦 支持的扫描包

包名 描述
react React 核心库
next Next.js 框架
react-server-dom-webpack RSC 的 Webpack 集成
react-server-dom-parcel RSC 的 Parcel 集成
react-server-dom-turbopack RSC 的 Turbopack 集成

🚀 安装指南

系统要求

  • Node.js 16 或更高版本
  • npm 或 yarn 包管理器

安装步骤

  1. 克隆此仓库或直接下载 check.js 文件到您的本地项目目录:

    git clone https://github.com/yourusername/check-react-rce-cve-2025-55182.git
    cd check-react-rce-cve-2025-55182
    

    (或者,将 check.js 文件复制到您想要扫描的 React/Next.js 项目根目录中。)

  2. 无需额外安装依赖,工具使用 Node.js 原生模块运行。

📖 使用说明

基础使用

  1. 将终端定位到包含 check.js 文件以及您要扫描的 package.json 的目录。

  2. 运行以下命令:

    node check.js
    

典型使用场景

工具将自动执行以下操作:

  1. 读取依赖:从 package.jsonnode_modules 中获取相关包的版本。
  2. 版本比对:将当前版本与已知的易受攻击版本范围进行比对。
  3. 分析代码结构:扫描项目文件,判断 Router 类型和 "use server" 的使用情况。
  4. 输出报告:在控制台中生成彩色、结构化的扫描报告,包含风险结论和修复建议。

输出示例

扫描完成后,您将看到类似如下的输出:

===========================================================================
             REACT RCE VULNERABILITY SCANNER (CVE-2025-55182)
===========================================================================

[项目分析]
📁 项目路径: /path/to/your/project
📦 检测到框架: Next.js (App Router)
🔎 发现 "use server" 指令: 是

[依赖版本]
🔄 react: 18.3.0-canary-... (易受攻击)
🔄 next: 14.0.0 (安全)
...

[风险结论]
❌ 严重风险:您的项目使用了易受攻击的 React 版本,并启用了 Server Actions。

[修复建议]
👉 请立即升级 react 到 18.3.1-canary-xxx 或更高版本:
   npm install react@latest react-dom@latest
...

💻 核心代码

以下是扫描工具的核心逻辑实现,展示了如何获取包版本并进行初步解析。

// check.js 核心片段
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

// 用于控制台彩色输出的ANSI转义码
const c = {
    red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m", blue: "\x1b[34m",
    cyan: "\x1b[36m", bold: "\x1b[1m", reset: "\x1b[0m", dim: "\x1b[2m"
};

/**
 * 获取指定npm包的已安装版本
 * 优先尝试从 'npm list' 命令获取精确版本,失败后回退到读取 package.json
 * @param {string} packageName 包名
 * @returns {string|null} 版本号或null
 */
function getPackageVersion(packageName) {
    // 尝试通过 npm list 命令获取版本信息(最准确)
    try {
        const output = execSync(`npm list ${packageName} --json`, { encoding: 'utf8', stdio: 'pipe' });
        const parsed = JSON.parse(output);
        if (parsed.dependencies && parsed.dependencies[packageName]) {
            return parsed.dependencies[packageName].version;
        }
        return null;
    } catch (e) {
        // 如果 npm list 报错(如包未安装),尝试解析其错误输出中的JSON
        if (e.stdout) {
            try {
                const parsed = JSON.parse(e.stdout);
                if (parsed.dependencies && parsed.dependencies[packageName]) {
                    return parsed.dependencies[packageName].version;
                }
            } catch (err) {}
        }
        // 最终回退方案:直接从 package.json 读取版本范围
        try {
            const pkg = require(path.join(process.cwd(), 'package.json'));
            const v = pkg.dependencies?.[packageName] || pkg.devDependencies?.[packageName];
            // 移除 ^ 或 ~ 符号以得到粗略版本
            return v ? v.replace(/[\^~]/g, '') : null;
        } catch (err) { return null; }
    }
}

/**
 * 解析版本字符串为主版本号、次版本号和修订号
 * 同时尝试解析canary版本的构建号
 * @param {string} vStr 版本字符串,如 "18.3.0-canary-xxx"
 * @returns {object|null} 包含 major, minor, patch, canary 的对象
 */
function parseVer(vStr) {
    if (!vStr) return null;
    // 移除预发布标签后缀(如 '-canary-xxx')以获取核心版本号
    const clean = vStr.split('-')[0];
    const [major, minor, patch] = clean.split('.').map(Number);

    // 解析canary版本号(如果存在)
    let canary = 0;
    if (vStr.includes('canary')) {
        const parts = vStr.split('.');
        const lastPart = parts[parts.length - 1];
        canary = parseInt(lastPart, 10) || 0;
    }
    return { major, minor, patch, canary };
}

// ... 后续代码包含版本比对、文件扫描和报告生成逻辑
```FINISHED
6HFtX5dABrKlqXeO5PUv/9JA46icxe/30dKWTNmxJiKvMXn9J0ckn8IqTD/AyRtl
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐