本文へスキップ
>_ITDITDセキュリティ対策プラットフォーム

技術別対策

脆弱性(CVE)対応の実務:直しきって、再発を監視し続ける手順

依存ライブラリの脆弱性(CVE)を、中小規模の現場で「直しきる」ための実務手順。スキャン→修正→隔離/引き継ぎ→監視という『完了の4定義』を背骨に、変化検知でアラート疲れを防ぐ、HTTP 200を信用しない、修正を消さない(local→push→deploy)、メジャー跨ぎは本番同一環境でビルド検証、といった現場の勘所を、当サイトの運用視点で解説します。

公開日 2026-06-11 更新日 2026-06-11 11分で読める

対象:少人数で複数のWebアプリ(フレームワーク混在)を運用していて、依存ライブラリの脆弱性(CVE)対応を「一度ちゃんと直しきりたい」人。ここでは攻撃手順は扱わず、直して・消えないようにして・監視し続けるまでの実務だけを扱います。きっかけになりがちな事故の例は 公開済みRCEを放置して不正課金された話 を参照。

当サイトの視点:小さな現場ほど『仕組み2つ』で守れる

人手が少ない現場で効くのは、派手なツールより2つの規律です。①自動の変化検知(増えた脆弱性だけ鳴らす)②local→push→deploy(本番は受け取るだけ、編集しない)。当サイトも同じ考えで、依存監査(pnpm audit)を毎デプロイ前+日次cronで回し、本番へは push-to-deploy で配るだけにしています。1回直すイベントではなく、鳴る仕組みを置いて回し続ける運用に倒すのが、結局いちばん安く長持ちします。

完了の「4定義」を先に固定する

中途半端に「終わった」と言わないための歯止めです。この4つが揃うまでは未完、と先に決めておきます。

① スキャン

現状を数字で把握する

② 修正

非devの重大/高を根治する

③ 隔離/引き継ぎ

直せない・孤立は明示的に

④ 監視

日次の変化検知を載せる

脆弱性対応の完了=4点セット。1つでも欠けると『直したつもり』で穴が残る。

① スキャン:現状を「数字」にする

まず、どこに何があるかを機械で把握します。手動の不定期チェックは必ず途切れます。

1

ロックファイルを自動探索してスキャン

composer.lock / package-lock.json / pnpm-lock.yaml を探し、OSSのスキャナ(osv-scannerpnpm audit)に毎日かける。ロックファイルを読むだけなので負荷はごく軽い。
2

重大度は『1つの数字』ではないと知る

同じ脆弱性が、CVSSでは高(例7.5)でもベンダー精査では中、ということは普通にある。CVSSは機械算出で過大評価しがち。どの基準で閾値を引くかを決め、チーム全員が『今どちらを使っているか』を共有する(→ CVSSとは)。実際に悪用されているか(KEV)と掛け合わせて優先度を出す。
3

ノイズは『無視』でなく『根拠を持って除外』

テスト/ビルド専用のdev依存は本番バンドルに載らないことが多く、実害が無い場合がある。スキャナのグループ判定でdevを通知から外しつつ、なぜ除外したかを台帳に残す。後で「これ直ってないけど?」に説明できる状態にしておく。

② 修正:対症療法でなく「根治」する

止血(対症療法)と根治は別作業です。両方やって初めて終わりです。

対症療法だけ(封じ込め止まり)

  • リバースプロキシで“それっぽい”リクエストだけ弾く
  • 症状が止まったので「対応完了」と考える
  • 脆弱な依存はそのままRCE等が生き続ける

根治(正しい)

  • 脆弱な依存を修正版へ更新して穴そのものを塞ぐ
  • 更新後、兆候が消えたかをログで確認
  • 止血と根治を別作業として両方やる

メジャー跨ぎは『本番に出す前にビルド検証』

パッチ当てと違い、メジャー版跨ぎ(フレームワーク14→15、UIツール4→6 等)は破壊的変更を伴う。盲目的に上げて本番ビルドが落ちると最悪。本番と同一ランタイム(同じNode/PHP版のコンテナ)に編集後ソースを置き、ビルド/型チェックを完全に通してから push する。落ちたエラーは1つずつ潰す(同期→非同期化のcodemod、CSSの複数行class、型名前空間の廃止 等)。旧コンテナが動き続ける構成なら、失敗時も無停止で切り戻せる。

修正の「永続性」まで含めて完了

中身が100点でも、次のデプロイで消える運用なら0点です。ここが一番やりがちな落とし穴。

1

本番の作業ツリーで直接commitしない

本番で直接commitすると中央リポと履歴が分岐し、次のデプロイ(pull / checkout -f)で上書きされて修正が消える。本番は『デプロイ結果を受け取る場所』であって編集する場所ではない。
2

必ず local→push→deploy の一方向に統一

編集はローカル→commit→push→(本番は)pull/自動デプロイ。やむを得ず本番で確認した変更も、必ずローカルへ巻き戻して push し直す(→ 本番は受け取るだけにする話)。
3

HTTP 200を『正常』と信じない

共用ホスティング等では、致命的エラーでも200が返ることがある。検証は必ず実コンテンツで——本文に期待する見出し/テキストが描画されているか(curl | grep)、エラーログに新規が出ていないか、DB依存やパラメータ付きの動的ルートまで踏む。キャッシュで反映が遅れることもあるので時間をおくかクリア後に。

③ 隔離/引き継ぎ:直せないものを「明示」する

全部を今すぐ直せるとは限りません。直せない・別管轄・もう使っていない、を曖昧にしないのがコツです。

1

孤立・EOLコードは『消す前に隔離』

もう配信していない旧ソース(EOLフレームワーク等)は、いきなり削除せずリネームで隔離し、「いつ・なぜ隔離したか・元の配信先」を書いたマーカーを残す。スキャン対象からも外す。『消す』は不可逆だが『隔離』は戻せて経緯も残る。
2

本当に未参照かを確定してから

リバースプロキシ設定・ビルド構成・マウントを追い、どこからも参照されていないことを確認してから隔離する。誤って再配信される事故の種を断つ。
3

直せない/別管轄は明示ハンドオフ

自分で直せないものは、放置でなく『誰に・何を』を明示して引き継ぐ。未対応を『見えない放置』にしないことが、棚卸しの価値。

④ 監視:日次の「変化検知」を載せて初めて完了

ここまで来て、最後に鳴る仕組みを置きます。これが無いと、せっかく直しても再発に気づけません。

『全部毎日鳴らす』でなく『増えたら鳴らす』

スキャン結果を前回との差分(state file)で比較し、新規の重大/高が出た時だけ通知する。毎日同じ内容が届くとすぐ無視される(アラート疲れ)。通知はメール1通に要約(新規・解消・現状)し、cronで日次。共用サーバーでもスキャナ1バイナリ+cronで十分回る(負荷は数ミリ秒〜・niceを噛ませれば安心)。

差分
増えた脆弱性だけ通知=疲れない
日次
cronで回し続ける
1通
新規・解消・現状を要約
④まで
監視を載せて初めて完了

棚卸しで一緒に出てくる「秘密」と「鍵」

CVEを直しきる過程では、依存以外の穴もよく一緒に見つかります。代表が2つ——公開ディレクトリに置き忘れた秘密ファイル(webrootに古いトークンが放置、共通テンプレ由来なら全台に同じ穴)と、侵害され得る一時環境に渡したroot鍵。どちらも「1か所漏れたら全部」を生む典型なので、CVE対応と同じ棚卸しのタイミングで点検します(この2つはそれぞれ単独で深掘りする価値があります)。秘密の基本は 秘密の安全な保管最低限チェックリスト を参照。

次に読む

よくある質問

Q脆弱性対応はどこまでやれば『完了』ですか?
A

4点が揃って初めて完了です。①スキャンで現状を数字にした②非devの重大/高を修正した③直せない・別管轄・孤立コードは明示的に隔離/引き継ぎした④日次の変化検知(再発・新規をキャッチする監視)を載せた。特に④を載せるまでは完了ではありません。依存は明日また脆弱になるからです。

Q毎日スキャンするとアラートに疲れませんか?
A

『全部を毎日鳴らす』とすぐ無視されます。前回結果との差分を取り、新規の重大/高が出た時だけ通知する『変化検知』にします。毎日同じ内容を送らないことが、結局いちばん長続きする設計です。

Q修正したのに、また脆弱に戻ることがあるのはなぜ?
A

本番の作業ツリーで直接commitすると、次のデプロイ(pull や checkout -f)で上書きされて修正が消えます。必ず local→push→deploy の一方向に統一し、本番は『受け取るだけ』にします。修正の中身が完璧でも、消える運用なら成果はゼロです。