このブログ(Next.js + microCMS、Vercel で運用)のリポジトリに、2026年10月23日の時点で Dependabot の脆弱性アラートが 39 件たまっていました。内訳は critical 6 件・high 11 件・moderate 17 件・low 5 件です。調査と更新作業は AI エージェント(Claude Code)に任せ、筆者は PR の確認とマージの判断を担当しました。最終的に npm audit が 0 件になるまでの記録です。
検証環境
- OS: macOS 26.7.1
- Node.js: v26.12.1 / npm: 11.20.0
- Next.js: 16.3.0 → 16.4.2、React 19.2.8
- ホスティング: Vercel
- 作業期間: 2026年10月23日〜24日
39 件の中身を仕分ける
件数を上から片付けるのではなく、まず「どのパッケージに集中しているか」「本番の実行時に読み込まれるものか」で仕分けました。Dependabot はアラートごとに依存の種類(runtime / development)を表示します。39 件をパッケージ別に数えると、大半が 2 つに集中していました。
- next: 16 件(critical 6 件を含む)
- undici: 10 件(HTML の解析に使っている cheerio 経由)
- 残りは sanitize-html・sharp・browserslist・brace-expansion・braces などが 1〜3 件ずつ
critical の 6 件はすべて Next.js でした。中身は 3 種類のリモートコード実行で、package.json と package-lock.json のそれぞれで 1 件ずつ数えられているため、6 件になっています。
next/ogの ImageResponse でのリモートコード実行(GHSA-vcvr-r3jv-pc5j)- Windows でホストしたサーバーでの、認証なしのリモートコード実行
- AVIF ファイルを使ったときの、画像最適化 API でのリモートコード実行
1 つ目は、このブログが実際に使っている機能の脆弱性でした。アイキャッチ画像が無い記事の OG 画像は、next/og の ImageResponse(Node.js 版)で、URL で受け取った記事タイトルを描画して生成しています(app/og/route.tsx)。勧告によると、成立するのは「攻撃者が操作できる値を SVG の中身・属性・スタイルに渡している場合」です。このブログはタイトルを SVG 要素ではなく文字として描画しているため、条件に当てはまるかは断定できません。それでも使っている機能そのものの穴なので、Next.js の更新を最優先にしました。2 つ目については、このブログは Windows サーバーでは運用していません。
PR 1:パッチ・マイナー更新で 38 件を解消
1 本目の PR では、メジャー更新をせずに上げられるものをまとめて更新しました。
- next / eslint-config-next: 16.3.0 → 16.4.2
- sanitize-html: 2.17.6 → 2.18.1
- sharp: 0.35.3 → 0.35.5
- undici: 7.29.0 → 7.30.1(lock ファイルのみ)
ポイントは Next.js の上げ先です。Dependabot のアラートが示していた修正版は 16.3.3〜16.3.8 で、16.3.8 に上げれば next のアラートはすべて消える状態でした。ところが、10月22日に GitHub の勧告データベースへ掲載された Next.js の脆弱性(GHSA-2464-fhr4-w9xw ほか計 3 件)は、まだアラートとして出ておらず、16.x では 16.4.1 以降でしか修正されていませんでした。16.3.8 で止めると、アラートは消えても穴が残ります。そのため 16.4.2 まで上げています。アラートの一覧だけを見ていると、この 3 件は見えません。
この PR で、本番の依存だけを対象にした監査は 0 件になりました。
$ npm audit --omit=dev
found 0 vulnerabilitiesPR では、lint・本番ビルド・開発サーバーでのトップと記事ページの表示(画像・コードのハイライト)・Vercel のプレビュー(OG 画像・サイトマップ・RSS)を確認しています。
39 件のうち、この PR で解消しなかった 1 件は braces(high)です。当時は修正版がなく、ESLint の実行時にだけ使われる開発用の依存だったため、残す判断にしました。このアラートはその日のうちに、コードを変えないまま GitHub 上で「解消」になりました。理由は確認できていません。
PR 2:あとから出たアラートを overrides で解消
PR 1 のあと、新しいアラートが 2 件出ました。1 件目は、CSS の装飾に使っている @tailwindcss/typography の中の postcss-selector-parser です(GHSA-rj75-hqrm-r3gf、moderate)。typography 0.5.20 がバージョン 6.0.10 に固定しているため、typography を最新にしても修正版の 7.1.6 になりません。
そこで、npm の overrides を使い、typography の配下だけに限定してバージョンを上書きしました。
"overrides": {
"@tailwindcss/typography": {
"postcss-selector-parser": "7.1.6"
}
}メジャーバージョンが変わる上書きなので、CSS の出力が変わらないかが問題になります。typography を読み込む CSS を変更前後でそれぞれビルドして比べたところ、出力はバイト単位で同一(46,712 bytes)でした。表示に影響がないことを数字で確かめたうえでマージしています。最新版の 7.1.7 は公開から日が浅かったため、7.1.6 に固定しました。
PR 3:開発時だけ使う zod を lock ファイルで更新
2 件目は zod(high、検証時にメモリを使い切るおそれ)でした。ESLint のプラグイン経由で入っている開発用の依存で、本番には入りません。既存のバージョン範囲内で 4.4.3 → 4.6.7 に上げられたため、変更は package-lock.json だけで済みました。
$ npm audit
found 0 vulnerabilitiesつまずいた点
- ビルドが microCMS のレート制限で落ちる。このブログはビルド時に microCMS から全記事を取得して 122 ページを生成します。短時間に何度もビルドすると 429(Too many requests)が返り、ビルドが失敗しました。依存の更新とは関係ない失敗なので、間を置いて再実行しています。
- 手元の node_modules が古いまま残る。マージ後に別の作業ブランチで
npm lsを実行すると、eslint-config-next@16.3.0 invalidと表示されました。lock ファイルは更新済みでも、手元でnpm ciし直さないと古い版のまま動きます。
AI エージェントとの分担
アラートの集計、各パッケージが本番に入るかを依存関係から辿る作業、ビルドや CSS 出力の比較は、エージェントが行いました。どのバージョンに上げたか、なぜそうしたか、何を確認したかは、毎回 PR の説明にまとめさせています。筆者はその説明を読んで確認し、マージするかを決めました。3 本の PR は、作成からマージまでそれぞれ 7 分・17 分・1 分ほどでした。
まとめ
- 39 件のアラートは、パッチ・マイナー更新の PR 1 本で 38 件が解消し、その後に出た 2 件も含めて
npm audit0 件になりました。 - 件数より先に「どこに集中しているか」「本番の実行時に入るか」で仕分けると、優先順位が決まります。今回は critical 6 件がすべて Next.js で、うち 1 つはこのブログが使っている
next/ogの脆弱性でした。 - アラートが示す修正版で止めず、公開されたばかりの勧告も確認します。今回は 16.3.8 ではなく 16.4.2 が必要でした。
- 直接上げられない推移的依存は
overridesで範囲を絞って上書きし、出力が同じかを比べてから入れます。
Dependabot の仕組みは GitHub Docs、npm audit と overrides は npm の公式ドキュメント(npm audit/package.json)にまとまっています。GitHub でのコード管理そのものについては「GitHubでコード管理を始めるべき理由」、AI エディタを使った開発については「Cursorを個人開発で使ってみた」でも書いています。




