サプライチェーンセキュリティ

サイトの npm 依存関係制御の背景にある脅威モデルと根拠

このページの内容は古くなっている可能性があり、一部のリンクが無効になっている場合があります。 このページのより新しいバージョン英語版にあります。

詳細情報 ...

このページが最後に更新されてからの英語ページの変更を確認するには、 GitHub compare 8d6b626b..08cb6781 にアクセスし、content/en/site/design/supply-chain-security.md を検索してください。

制御の詳細と日常の手順については、Dependency management を参照してください。 関連するセキュリティトピックにはそれぞれ専用のページがあります。 ワークフローのトリガーとトークン権限については CI workflows を、脆弱性の報告については security policy を参照してください。

脅威モデル

2026年8月の npm ワーム(security notice)が現在のセキュリティ態勢を定めました。 侵害されたメンテナーアカウントから、人気のある npm パッケージの悪意あるバージョンが公開されました。 パッケージのインストール時の lifecycle scripts がペイロードを実行し、窃取した認証情報を使って伝搬しました。 このリポジトリのいくつかの PR ブランチが封じ込め前に影響を受けましたが、main や本番環境には到達しませんでした。

このリポジトリに関連する攻撃経路は以下のとおりです。

  • バージョン解決: バージョン範囲を解決するインストールは、新しく公開された悪意あるリリースを取得する可能性があります。
  • ライフサイクルスクリプト: インストール時のスクリプト実行により、悪意あるパッケージがコントリビューターのホスト、CI ランナー、ビルドイメージを侵害できます。
  • 無人インストール: CI ジョブや Netlify のビルドイメージは人間の監視なしにインストールを実行します。 エージェントセッションも同様です。

設計上の決定

共通するテーマはフェイルクローズです。 制御を強制できない場合、制御なしで続行するのではなく、インストールが失敗します。

各決定は攻撃経路に対応しており、おおむね作用するタイミング順に並べています。 末尾の表で決定とその適用方法を対応付けています。

  • 直接的・推移的を問わず、すべての依存関係は攻撃者が到達できる攻撃対象領域である。
    • 依存関係を最小化する: 未使用の依存関係や利便性のためだけの依存関係は、維持するのではなく削除します。
  • バージョン範囲を解決するインストールは、新しく公開された悪意あるリリースを取得する可能性がある。
    • ロックファイルからインストールする: インストールはロック完全一致で行われ、コミット済みでレビュー済みの package-lock.json を再現します。 唯一の例外として、ローカルの npm install は不一致のロックファイルを書き換えることがあります。 検証がそのような書き換えを検出します。
    • 意図的に解決する: バージョン解決は意図的な依存関係更新でのみ行われ、インストールの副作用としては行われません。
    • クールダウン済みのリリースのみを解決する: 意図的な解決であっても、クールダウン期間より新しいリリースは無視します。 悪意あるリリースのレジストリ側での削除には数日かかります。
  • パッケージのインストール時スクリプトは、コントリビューターのホストやビルドマシン上で攻撃者のコードを実行する。これがワームのペイロード経路だった。
    • レビュー済みのライフサイクルスクリプトのみを実行する: lifecycle scriptsデフォルト拒否です。
      • 承認はバージョン完全一致であるため、侵害されたパッチリリースが前のバージョンの承認を引き継ぐことはできません。
      • レビューは拒否も記録するため、記録がないことは常に未レビューを意味します。
      • 例外は使用箇所でインラインで名前付きで再有効化されます。 デフォルトの態勢を弱めることはありません。
  • Netlify の独自の npm install は無人で実行され、このリポジトリが制御するスクリプトの範囲外であり、無効化できない。
  • 制御が暗黙のうちに適用されなくなることは、制御がないことよりも悪い。
    • 古い npm ではフェイルクローズする: アクティブな npm が .npmrc の設定を適用するには古すぎる場合、続行するのではなくインストールが失敗します。
    • 信頼せず検証する: 無効化とロック完全一致は、前提ではなく検証済みの主張です。

適用方法の一覧:

決定適用方法
Minimize dependencies依存関係レビュー時のメンテナーの判断。機械的な制御はなし
Install from the lockすべてのインストール契約での npm ci
Resolve deliberately慣例に基づく。ロックファイルが裏付け: 予期しない解決はロックファイルを書き換え、検証がそれを検出する
Resolve only cooled-down releasesnpm と Renovate の両方に対するクールダウン制御
Run only reviewed lifecycle scripts厳格モードの許可リスト。未レビューの場合はインストールが失敗する
Neutralize the auto-install自動インストール無効化制御
Fail closed on old npm厳格なエンジンチェック付きの npm エンジンフロア
Verify, don’t trustビルドを失敗させるクリーンワーキングツリーチェック。ローカルでのロックファイル書き換え時の postinstall 警告

先行事例

  • デフォルト拒否のライフサイクルスクリプトはエコシステムの方向性です。
    • pnpmYarn はデフォルトで依存関係のスクリプトをブロックします。
    • npm の承認済み RFC #54allowScripts を通じて同じモデルを npm にもたらします。 バージョン完全一致のエントリも含まれています。
  • リリースクールダウンは確立されたプラクティスです。
  • この制御セットは確立されたフレームワークのガイダンスに対応しています。
    • TUF の攻撃分類: 任意のソフトウェアインストール、ミックスアンドマッチ、および余分な依存関係攻撃。
    • OpenSSF npm ガイド: ロック完全一致の CI インストール。