この記事は約 5 分で読めます。
筆者プロフィール: ソフトウェアエンジニア。「知った気にならない。いつまでも学び続ける」を信条に、業務と個人開発の両輪で技術を磨いています。AI 駆動開発で複数の個人開発アプリを構築・運用中。
👉 ポートフォリオ: 筆者ホームページ
最近のサプライチェーン攻撃 (有名ライブラリの乗っ取り) を踏まえ、依存パッケージ管理を厳重に する話を整理します。運用中の SaaS 「たすきば Knowledge Relay」 で実装している pnpm audit + Renovate + 事前審査の運用。
サービスの機能紹介・画面イメージ・コンセプトは公式プロダクトページをご覧ください。
👉 たすきば Knowledge Relay — 公式プロダクトページ
なぜ依存管理が重要か
たすきばの依存パッケージ:
| 階層 | 数 |
|---|---|
| 直接依存 | 50〜70 個 |
| 推移的依存 | 数百〜数千個 |
この中に脆弱性が混入すると、サービス全体に影響。最近のサプライチェーン攻撃を踏まえ、依存管理を厳重に します。
1. CI での脆弱性監視
.github/workflows/security.yml の一部:
- name: pnpm audit
run: pnpm audit --prod --json > audit-report.json
- name: Check for critical
run: |
CRITICAL=$(jq '.metadata.vulnerabilities.critical' audit-report.json)
HIGH=$(jq '.metadata.vulnerabilities.high' audit-report.json)
if [ "$CRITICAL" -gt 0 ]; then
echo "::error::$CRITICAL critical vulnerabilities found"
exit 1
fi
| severity | 対応 |
|---|---|
| Critical | CI 失敗 → PR マージ不可 |
| High | 警告 (スコア減点) |
| Moderate / Low | 監視のみ |
セキュリティスコア 90 点強制と連動して、深刻な脆弱性を構造的に排除。
2. Renovate で自動更新
// renovate.json
{
"extends": ["config:base"],
"schedule": ["before 6am every weekday"],
"vulnerabilityAlerts": {
"enabled": true,
"labels": ["security", "urgent"]
},
"packageRules": [
{
"matchUpdateTypes": ["patch", "minor"],
"automerge": true
},
{
"matchUpdateTypes": ["major"],
"automerge": false
}
]
}
| 設定 | 内容 |
|---|---|
| 実行頻度 | 平日朝 6 時前 |
| patch / minor | 自動マージ (CI 通過後) |
| major | 人間レビュー必須 |
| 脆弱性 | 緊急対応として優先処理 |
3. 個人開発で自動マージは安全か
自動マージは怖い。ただし:
| 理由 | 内容 |
|---|---|
| semver の定義 | patch / minor は後方互換性保証 |
| CI 通過後 | バグなら CI で検知 |
| revert 可能 | 何かおかしければ戻せる |
実際 6 ヶ月運用して、自動マージで事故は 1 件もありません。むしろ「こまめに最新化される」ことで、major 移行時の負担が減ります。
4. major アップデートは慎重に
major アップデートは breaking change を含む可能性が高い。
1. Renovate が PR を立てる (自動マージなし)
2. リリースノート / changelog を確認
3. ローカルで動作確認
4. 影響範囲をテストで verify
5. 問題なければマージ
特に Next.js / React / Prisma などのコアライブラリは、major アップデートで API 変更が頻繁。慎重に進めます。
5. 新規 npm 追加時の事前審査
新しいパッケージを追加するときは、以下を審査。
信頼性
□ 週間ダウンロード数 (10,000 以上が目安)
□ メンテナンス状況 (直近 6 ヶ月以内に更新あり)
□ GitHub の Star 数 / Issue 数 / 対応状況
□ 既知の脆弱性
必要性
□ そのパッケージでないと実装できないか
□ 既存の依存で同等の機能を実現できないか
□ 自前実装が現実的か
サイズ・パフォーマンス
□ bundle サイズへの影響
□ 推移的依存の数
□ ランタイムのオーバーヘッド
代替手段
□ 競合ライブラリとの比較
□ 標準 API (Node.js / Web 標準) で代替できるか
6. 自前実装寄りの判断
たすきばは 「外部ライブラリを使わなくても実装できる箇所は独自実装を選ぶ」 を方針。
| 理由 | 内容 |
|---|---|
| サプライチェーンリスク低減 | 外部依存を最小化 |
| デバッグしやすさ | 自前実装は理解可能性が高い |
| メンテナンス終了からの独立 | ライブラリ消失リスクなし |
具体例:
| 機能 | 採用 |
|---|---|
| TOTP (MFA) | otplib (枯れている) |
| QR コード生成 | qrcode (標準的) |
| CSV パーサ | 自前実装 (シンプルな仕様) |
| Markdown レンダラ | react-markdown (XSS 対策込み) |
「標準的で枯れたライブラリ」と「自前実装」を 文脈で使い分け。
7. サプライチェーン攻撃への警戒
最近の攻撃事例:
| 攻撃 | 内容 |
|---|---|
| アカウント乗っ取り | 有名ライブラリで悪意あるバージョン公開 |
| 推移的依存マルウェア | ライブラリの依存にマルウェア混入 |
| typosquatting | 似た名前のパッケージ |
これらを防ぐため:
□ pnpm install --frozen-lockfile で意図しない更新を防止
□ overrides で特定バージョンを強制
□ 新規パッケージは事前審査
□ lockfile に hash を含める (改ざん検知)
8. lockfile の hash 検証
pnpm の pnpm-lock.yaml には、各パッケージの integrity hash が含まれます。
'@types/node@20.10.0':
resolution: {integrity: sha512-...}
pnpm install --frozen-lockfile 時、これがチェックされる。hash が一致しないと install 失敗。
サプライチェーン攻撃で、同じバージョンの内容が改ざんされた場合に検知 できます。
9. GitHub Dependency Review
.github/workflows/dependency-review.yml:
on: [pull_request]
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
PR レベルで:
□ 新規パッケージのリストを表示
□ 脆弱性の有無を表示
□ ライセンスの確認
PR レビュー時に依存追加を可視化 できます。
おわりに
| 仕組み | 効果 |
|---|---|
| CI で pnpm audit (Critical で fail) | 深刻な脆弱性を構造的に排除 |
| Renovate で自動更新 | こまめな最新化 |
| 新規 npm の事前審査 | サプライチェーン警戒 |
| 自前実装 + DRY | 外部依存を最小化 |
| lockfile の integrity hash | 改ざん検知 |
| 脆弱性 KDD | 学習の蓄積 |
| GitHub Dependency Review | PR レベルの可視化 |
サプライチェーン攻撃時代の、依存管理の最低ライン です。
本記事の依存管理は、運用中の SaaS 「たすきば Knowledge Relay」 で実装しています。
👉 たすきば Knowledge Relay — 公式プロダクトページ