暗号化されていないプロトコルによる依存関係のダウンロード

暗号化されていないプロトコルによる依存関係のダウンロード

説明

HTTP や FTP などの暗号化されていないプロトコルで依存関係を取得すると、通信中に盗聴や改ざんを受けるおそれがあります。同じネットワーク上の攻撃者、悪意のあるプロキシ、DNS スプーフィング、侵害されたミラーサーバーによって tarball などが差し替えられ、インストールやビルド時に悪意のあるコードが実行される可能性があります。

想定される影響

  • 改ざんされたパッケージやインストールスクリプトによる任意コード実行
  • 悪意のある依存関係が製品に組み込まれ、本番環境まで届くサプライチェーン侵害
  • ビルドの完全性やリリース成果物への信頼の喪失
  • 通信中に露出したメタデータやアーティファクトの窃取、改ざん

対処方法

  • npm の tarball URL には HTTPS を使い、Git の依存関係にはサポートされる HTTPS または検証済みの SSH 接続を使ってください。
  • 可能なら npm などの公式レジストリのバージョン範囲を指定し、外部 URL の直接指定を減らしてください。
  • .npmrc などで strict-ssl=true と HTTPS のレジストリを設定し、内部アーティファクトサーバーにも有効な証明書と適切な TLS 設定を使ってください。
  • レビュー済みの package-lock.json または npm-shrinkwrap.json をコミットし、npm ci を使ってください。integrity は記録されたアーティファクトと一致するかを検証しますが、その内容自体の信頼性は保証しません。
  • チェックサムや GPG などの署名がある場合は、信頼する値やキーで検証してください。
  • CI では HTTP の外向き通信を遮断し、許可したドメインとの通信だけに制限してください。
  • CI で npm config set ignore-scripts true を検討し、必要なインストールスクリプトだけを別途許可してください。

例

変更前

HTTP は暗号化されていないダウンロードの例です。現在の npm は FTP URL をサポートせず、インストールが失敗する可能性があります。実際に FTP 通信が行われるとは限りません。

javascript
{
  "name": "demo-app",
  "version": "1.0.0",
  "dependencies": {
    "left-pad": "http://mirror.local/libs/left-pad-1.3.0.tgz",
    "my-utils": "ftp://downloads.example.org/my-utils-2.1.0.tgz"
  }
}

変更後

package.json:

json
{
  "name": "demo-app",
  "version": "1.0.0",
  "dependencies": {
    "left-pad": "^1.3.0",
    "my-utils": "https://repo.example.com/npm/my-utils-2.1.0.tgz"
  }
}

プロジェクトまたは CI 環境の .npmrc:

ini
registry=https://registry.npmjs.org/
strict-ssl=true
# 内部レジストリにも HTTPS を使用
@company:registry=https://repo.example.com/npm/

説明:

  • 変更前: HTTP ダウンロードには通信中に tarball を改ざんされるリスクがあります。FTP の項目は現在の npm でサポートされない設定です。悪意のあるパッケージコードや postinstall などが、ビルド環境や開発者の環境で実行される可能性があります。
  • 変更後: HTTPS で通信を暗号化し、接続先を認証します。レジストリのバージョン範囲を使って直接 URL を減らし、.npmrc の strict-ssl で TLS 検証を有効にします。レビュー済みのロックファイルの integrity と異なるダウンロードは拒否されます。ただし、悪意のあるパッケージや、同時に改ざんされたロックファイルまで信頼できるようになるわけではありません。

参考資料