npm install 時の postinstall スクリプトでマルウェアが実行されるpackage-lock.json + npm ci で再現性を固めることが基本的な予防策npm audit は既知の脆弱性のみ検知。ゼロデイには Socket.dev が有効ソフトウェアの調達ルートを狙い、信頼済みライブラリを汚染することで間接的に侵入する攻撃。
通常の攻撃:
攻撃者 → あなたのアプリ(直接)
サプライチェーン攻撃:
攻撃者 → ライブラリ(汚染)→ あなたのアプリ(間接)
① メンテナのnpmアカウントを乗っ取る
↓
② 悪意あるバージョン(axios@1.14.1)を公開
↓
③ 悪意ある依存「plain-crypto-js@4.2.1」を仕込む
↓
④ npm install 時に postinstall スクリプトが自動実行
↓
⑤ 開発者PCやCI環境にRAT(遠隔操作マルウェア)が展開
💡 ポイント: 自分は何も悪いことをしていないのに、普通に
npm installするだけで感染する。コードでaxiosを一度も呼ばなくても、インストール時点で実行される。
STEP 1: 実際にインストールされているバージョンを確認
↓
STEP 2: 悪意ある依存パッケージの有無を確認
↓
STEP 3: npm audit で既知の脆弱性を一括チェック
# STEP 1: バージョン確認
npm list axios
grep '"axios"' package-lock.json
# STEP 2: 悪意ある依存の確認
npm list plain-crypto-js
grep 'plain-crypto-js' package-lock.json
# STEP 3: 脆弱性チェック
npm audit
💡 ポイント:
package.jsonよりpackage-lock.jsonが実態に近い。ロックファイルを必ず確認すること。また^1.13.2のような指定は、マイナー・パッチバージョンアップを許容するため、将来的に侵害版が入るリスクがある。
① 監視ツールを入れる → 脆弱性を自動検知
② npm の運用を固める → 危険なインストールを防ぐ
③ CI に組み込む → マージ前に自動チェック
# ロックファイルを厳守(CI環境では必須)
npm ci
# postinstall スクリプトの実行を防ぐ
npm install --ignore-scripts
# ⚠️ esbuild など一部の正規パッケージも動かなくなる場合あり
# .github/workflows/audit.yml
name: Security Audit
on:
push:
branches: [main]
pull_request:
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm audit --audit-level=high
💡 ポイント:
--ignore-scriptsはCI・本番ビルドで有効。開発環境では正規パッケージへの影響を考慮して使い分ける。
① 検知・確認 → 本当に影響があるか事実確認
↓
② 隔離・修正 → 安全なバージョンに戻す
↓
③ 被害確認 → マルウェアが実行されたか調べる
↓
④ ローテーション → 漏れた可能性のある認証情報を無効化
# ② 安全なバージョンに戻す
npm install axios@1.14.0
# node_modules を完全に作り直す
rm -rf node_modules package-lock.json
npm install
# ③ postinstall 実行ログの確認
cat ~/.npm/_logs/*.log | grep postinstall
# ④ ローテーションチェックリスト(Next.js + Supabase構成)
□ Supabase の service_role キーを再発行
□ .env に入っている全APIキーを無効化・再発行
□ GitHub Personal Access Token を再発行
□ GitHub Actions の Secrets を更新
□ npm アクセストークンを再発行
□ Vercel の環境変数を更新
💡 ポイント: 「実行されたか不明」= 実行された前提で動く。ローテーションの手間よりリスクを取る判断が正解。コストの非対称性で考える。
インストール前 → Socket.dev
インストール時 → npm audit
開発・PR時 → Snyk / Dependabot
CI実行時 → npm audit(CI組み込み)
| ツール | 検知タイミング | ゼロデイへの有効性 | 導入コスト |
|---|---|---|---|
npm audit | インストール後 | △ DB登録後のみ | ほぼゼロ |
| Dependabot | PR・定期 | △ DB登録後のみ | 低 |
| Snyk | PR・定期 | △ DB登録後のみ | 低 |
| Socket.dev | インストール前 | ◎ 挙動分析 | 低 |
# Dependabot 設定(.github/dependabot.yml)
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
💡 ポイント:
npm auditは既知の脆弱性DBと照合するため、公開直後のゼロデイは検知できない。Socket.dev はパッケージの挙動(postinstall追加・難読化・外部通信など)を分析するため、DB登録前でも検知できる。
| ミス | 改善策 |
|---|---|
npm install をCIで使う | npm ci に切り替えてロックファイルを厳守する |
package-lock.json をgitignoreに入れる | 必ずコミットして実態を管理する |
npm audit だけで安心する | Socket.dev など挙動分析ツールも併用する |
| 侵害が疑わしいのに様子を見る | 疑い段階で即ローテーションする |
^ の意味を把握せず使う | バージョン指定の意味を理解した上でロックファイルで管理する |