技術別対策
Next.js を安全に運用する:公開済みCVEに後れを取らないしくみ
Next.jsのようなフレームワークで一番怖いのは、公開済みの脆弱性(CVE)を放置することです。実際にCVSS 10.0級のRCEを数ヶ月放置して踏まれた事故もあります。実稼働版での判定(package.json下限の罠を図解)、依存の機械監視、更新規律、最小権限という4本柱で、後れを取らないしくみの作り方を、ITDの運用視点で解説します。
対象:Next.js(や類似のJSフレームワーク)でアプリを作って公開している人。とくに「AIに手伝ってもらって作って、運用は手探り」という人向けです。実際の事故(→ 放置したCVSS 10.0の話)から抽出した、後れを取らないための4本柱です。
ITDの視点:勝負どころは“速さ”ではない
個人開発者がセキュリティで負けるのは、たいてい知識不足ではなく 「運用の継続性」 です。CVE速報を誰より早く読むことに価値はありません(速さはベンダーやニュースに任せればいい)。効くのは 「自分に関係するCVEを、見落とさない仕組み」。だからこの記事は“知識”ではなく“仕組み化”に振っています。
1. 実稼働版で判定する
「危ないバージョンを使っているか」は、package.json の下限表記ではなく、実際に動いているバージョンで測ります。なぜなら、マニフェストの数字と実際に動く版はしばしば食い違うからです。
✗ package.json の下限で数える
"next": "^16.0.0" →「16.0.0が脆弱だから危険」と誤判定。「8個脆弱」と過大カウント。
✓ 実稼働版で数える
npm ls next で実際の解決版を確認 → 自動更新済みは安全、固定ピンだけ危険。本当は2個。
# 実際に解決されている版を確認
npm ls next react react-dom
# 稼働中コンテナの中で確認
docker exec <container> npm ls next^16.0.0 のようなキャレット表記は、再ビルドで自動的に上がる範囲がある一方、固定ピンの依存は取り残されます。ここに出る数字が真実です。
2. 依存を機械監視する
CVEを人力で追うのは不可能で、その見落としが事故になります。機械に見張らせます。
無料で始められる依存監視
# OSV スキャナでロックファイルを検査(CIに1ステップ)
osv-scanner --lockfile=pnpm-lock.yamlGitHub なら Dependabot を有効化(Settings → Security)。自分の依存に該当するCVEだけが自動でPR通知されます。
監視では優先度が肝心です。ITDの考えでは、優先順位は「実際に悪用されているか(KEV)」と「CVSSの高さ」を掛け合わせて決めます。CVSSの数字が高くても未使用なら影響は小さく、中スコアでも悪用中なら最優先——この優先度判断こそが運用の本体です。
3. 更新規律:症状隠しでなく根本を直す
脆弱性が見つかったら、フレームワーク本体を修正版へ更新して穴そのものを塞ぎます。
症状隠し(不十分)
- リバースプロキシで“それっぽい”リクエストだけ弾く
- 課金や症状を止めて「対応完了」と考える
- RCE 自体は生きたまま放置
根本修正(正しい)
- フレームワーク本体を修正版へ更新して穴を塞ぐ
- 更新後、脆弱性の兆候が消えたかをログで確認
- 止血と根本修正を別作業として両方やる
やりがちな失敗
「課金や症状を止めた」≠「対応完了」。止血と、脆弱性そのものを塞ぐのは別作業です。両方やって初めて完了です。
4. 最小権限で爆発半径を小さく
万一踏まれても被害を閉じ込める設計にします。
非特権ユーザーで動かす
USER を root にしない。踏まれても“その権限”までしか被害が及ばない。DB・Redisは内部ネットだけに
サービスごとに分離
これらは、漏れたときに「コンテナ内のenv窃取で止まる」か「ホスト乗っ取りまで行く」かの分かれ目になります。
ITD自身も同じ対策を実践している
ITD自身も、ここで書いた通りに自分の依存をCVE監視の対象にしています。発端になった事故(公開済みCVSS 10.0の見落とし)を、二度と人が見落とさないように——機械に見張らせるを製品の説得力にしています。私たちが「優先度(KEV+CVSS)で見る」と書くのは、自分たちがそう運用しているからです。
次に読む
- 事故:公開済みRCEを放置して不正課金された話
- 用語:CVE / CVSS / RCE
- 歴史:Log4Shell — 依存経由のRCE
よくある質問
QNext.js のセキュリティで一番大事なことは?
自分でバグを書かない以前に、『フレームワーク本体や依存の公開済みCVEを放置しない』ことです。多くの深刻事故は新種の攻撃ではなく、既知の穴の放置から起きています。
Q脆弱かどうかは package.json を見ればいい?
いいえ。package.json の `^` 表記(下限)は実態と違います。再ビルドで自動更新される範囲もあれば、固定ピンで取り残される依存もあります。必ず『実際に動いているバージョン』で判定してください。
Q個人開発で最初にやるべき1つは?
Dependabot(GitHub)か osv-scanner を有効化して、依存のCVEを機械に見張らせることです。人力の巡回は必ず抜けます。仕組みで継続することが、知識より効きます。