security
A
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
サプライチェーン攻撃と依存関係の脆弱性管理
npmパッケージへの悪意ある改ざん・依存関係の脆弱性など、サプライチェーン攻撃の手口と対策を解説。Dependabot・Socket・署名検証・lockfileの重要性を説明します。
一言結論
サプライチェーン攻撃はlockfileのコミット・npm ciの使用・Dependabotによる自動更新・npm auditのCI組み込みという4つの基本対策を実施するだけで、現実的なリスクの大部分を低減できる。
サプライチェーン攻撃とは
直接のコードではなく、コードが依存する「サプライチェーン」を攻撃する手法
典型的な手口:
1. 人気パッケージにマルウェアを仕込んで公開(typosquatting含む)
2. メンテナのアカウントを乗っ取ってパッケージを改ざん
3. 悪意あるパッケージを依存として潜り込ませる
4. パッケージの廃止・reuse によるリネーム攻撃
実際の事例:
- event-stream事件(2018): 人気パッケージに暗号通貨を盗むコードが挿入
- colors.js・faker.js(2022): 作者が意図的に壊してDOSコードを追加
- XZ Utils(2024): Linux のコアライブラリにバックドアが仕込まれる寸前
対策1: Lockfile を必ずコミットする
# ✅ package-lock.json / yarn.lock / pnpm-lock.yaml をコミットする
# これにより、依存関係の正確なバージョンが固定される
# ❌ npm install(lockfileを無視して最新を取得する可能性)
npm install # package.json の範囲内で最新をインストール
# ✅ CI では npm ci を使う(lockfileに完全に従う)
npm ci
対策2: Dependabot / Renovate で脆弱性を自動検出
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
groups:
dev-deps:
patterns: ["eslint*", "prettier*", "@types/*"]
ignore:
- dependency-name: "lodash"
update-types: ["version-update:semver-major"]
security-updates-only: false
対策3: npm audit を CI に組み込む
# .github/workflows/security.yml
- name: Security audit
run: |
npm audit --audit-level=high
# high 以上の脆弱性があればビルドを失敗させる
# 手動で確認
npm audit
npm audit --json | jq '.vulnerabilities | to_entries[] | select(.value.severity == "critical")'
# 修正可能なものを自動修正
npm audit fix
# 破壊的変更が伴う場合も強制修正(注意して使う)
npm audit fix --force
対策4: パッケージの信頼性を確認する
インストール前にパッケージを調査する習慣を:
# socket.dev でパッケージの安全性を確認
npx socket info <package-name>
# npm のダウンロード数・更新頻度を確認
npm show <package-name> time.modified
npm show <package-name> downloads.weekly
確認する観点:
- ダウンロード数(低いものは要注意)
- 最終更新日(長期放置は危険)
- メンテナ数(1人だとリスク高)
- リポジトリに Issue・PR が活発か
対策5: package.json の overrides でバージョンを固定
推移的な依存関係(依存の依存)に脆弱性がある場合:
{
"overrides": {
"lodash": "4.17.21",
"minimist": "1.2.8"
}
}
対策6: .npmrc でパブリッシュ先を制限
# .npmrc
registry=https://registry.npmjs.org/
# プライベートスコープはプライベートレジストリに
@myorg:registry=https://npm.mycompany.com/
# package-lock.json の整合性チェックを強制
package-lock=true
対策7: npm の provenance(来歴)を確認
2023年から npm は provenance attestation をサポートしています:
# パッケージの署名と来歴を確認
npm audit signatures
# 来歴付きでパブリッシュ(GitHub Actions から)
npm publish --provenance
対策8: 依存関係の最小化
原則: 依存は少ないほど良い
よくある過剰依存の例:
❌ is-even(0+1本)を使う for 偶数チェック
✅ n % 2 === 0 をそのまま書く
❌ left-pad
✅ String.prototype.padStart(ネイティブ)
まとめ
| 優先度 | 対策 |
|---|---|
| 必須 | lockfile をコミット・CI で npm ci を使う |
| 必須 | npm audit を CI に組み込む |
| 推奨 | Dependabot / Renovate で自動更新 |
| 推奨 | 新規パッケージ追加時は socket.dev で確認 |
| 推奨 | 依存関係を必要最小限にする |