NPM Provenance: JavaScriptライブラリに欠けていたセキュリティレイヤーを補う

安全なJavaScriptアプリケーションにおいて、パッケージの出所検証が不可欠である理由

Jakub Pavlik

Jakub Pavlik

Marco Rodrigues

Marco Rodrigues

人気ライブラリであるlottie-playerをめぐる最近のセキュリティインシデントは、NPMエコシステムのセキュリティがいかに脆弱であるかを改めて浮き彫りにしました。NPMはprovenance attestationなどの強力なセキュリティ機能を提供していますが、ダウンロード数の多いパッケージの多くでは、こうした重要なセキュリティ対策が活用されていません。

NPM Provenanceとは

NPM Provenanceは、公開されたパッケージとそのソースコードリポジトリの間に、検証可能な関連付けを作成するセキュリティ機能で、昨年導入されました。有効化すると、そのパッケージが特定のGitHubリポジトリのコミットから、GitHub ActionsまたはGitLabランナーを使ってビルドされたことを暗号学的に証明できます。これにより、悪意のある攻撃者が人気パッケージの改ざん版を公開するようなサプライチェーン攻撃の防止に役立ちます。

ただし、このセキュリティはビルド環境自体の完全性に依存している点に注意が必要です。GitHub/GitLabアカウントやCI/CDパイプラインが侵害された場合、悪意のあるコードに対してもprovenance attestationが生成される可能性があります。そのため、強力なアクセス制御、監査ログ、定期的なセキュリティレビューによって、ソースコード管理基盤とCI/CDインフラを保護することが引き続き重要です。

Built and signed on GitHub Actions

人気の高いNPMパッケージの現状

ダウンロード数の多いNPMパッケージと、そのprovenance対応状況を見てみましょう。

Table comparing Lodash, React, and Express npm packages—showing usage, GitHub presence, lack of provenance, and related supply chain risks

jsDelivrでダウンロード数上位2,000件のパッケージのうち、205件は公開GitHubリポジトリを持ち、GitHub Workflowsを使ってnpmへ直接公開しています。しかし、このうちprovenanceを有効にしているのは26件(12.6%)にとどまります。provenanceは、パッケージがどこで、どのようにビルドされたかを検証するセキュリティ機能です。GitHub Workflowsにこの比較的小さな変更を加えるだけでも、コミュニティ全体のセキュリティを大きく向上させることができます。

NPMのセキュリティモデルにおける重大なギャップ

Diagram of current NPM software supply chain showing security gaps: missing provenance, attestation, tag verification, and client checks

サーバー側の制限

現在のNPMレジストリには、重要なサーバー側の強制メカニズムが欠けています。

1. provenanceの必須化がない

  • パッケージはattestationなしでも公開できます。
  • 特定のパッケージや組織に対してprovenance要件を強制する方法がありません。
  • レジストリは、検証の有無にかかわらずパッケージを受け入れます。

2. ポリシー制御の不足

  • 組織はパッケージ公開要件を設定できません。
  • Gitのブランチ保護と同様に、特定のパッケージ名や命名パターンに対してprovenanceを強制する機能がありません。
  • ビルド元の真正性を自動検証する仕組みがありません。

3. バージョン管理

  • 一致するprovenanceがないバージョン更新を防ぐ仕組みがありません。
  • メジャーバージョン更新に対して、より厳格な要件を強制できません。

クライアント側の検証ギャップ

npm/yarnクライアントツールにも、重要なセキュリティ制御が不足しています。

1. インストールプロセス

2. 不足しているセキュリティ機能

  • provenanceを必須にする組み込みフラグがありません。
  • 組織全体のattestationポリシーを強制できません。
  • 単一パッケージのattestationを検証する方法がありません。

3. package.jsonの制限

lottie-playerインシデント

最近のlottie-playerライブラリ侵害は、何が起こり得るかを痛烈に示す事例となりました。攻撃の流れは次のとおりです。

  1. 攻撃者がメンテナーのNPMアカウントへアクセスした。
  2. 悪意のあるバージョンのパッケージを公開した。
  3. ユーザーは、バージョン固定されていない依存関係の更新やCDNへの直接リンクを通じて、侵害されたバージョンを自動的に取得した。
  4. 影響を受けたシステム上で悪意のあるコードが実行された。

provenance attestationがレジストリ側またはクライアント側で強制されていれば、この攻撃は防げた可能性があります。

なぜ、より多くのパッケージでProvenanceが使われていないのか

NPM Provenanceの採用率が低い背景には、いくつかの要因があります。

  1. 認知不足: 多くのメンテナーがこの機能を十分に認識していません。
  2. 実装負荷: GitHub Actionsワークフローの修正が必要です。
  3. レガシーシステム: 既存のビルドパイプラインでは、大幅な更新が必要になる場合があります。
  4. 誤った安心感: 2FAなど、他のセキュリティ対策に依存しているケースがあります。
  5. 強制力の欠如: レジストリ要件がないため、導入を迫る圧力がありません。
Diagram of a recommended secure NPM model showing build, registry, client, and CDN security with provenance, OIDC, and SRI validation

NPMパッケージでprovenanceを有効にするには、次のようにします。

または、package.jsonで設定します。

パッケージのProvenance確認

npmコマンドのauditでは、パッケージの完全性と真正性を確認できますが、個別のパッケージを検証することはできません。確認できるのは、プロジェクト内の全パッケージをまとめた検証のみです。

無効なattestationを持つNPMパッケージ

npm CLIにはこれを簡単に行う方法がないため、私は個々のパッケージの完全性とattestationを確認するためのシンプルなスクリプトを書きました。このスクリプトを使えば、各パッケージを簡単に検証できます。

このスクリプトは、クライアント側のGitHub Workflowで使用することも、上流パッケージのattestationを継続的に確認する監視ツールとして使用することもできます。

クライアント側スクリプトの整合性検証

NPM Provenanceはパッケージエコシステムの保護に役立ちますが、CDNリンク経由でJavaScriptを直接読み込むWebアプリケーションには、追加のセキュリティ対策が必要です。Subresource Integrity(SRI)は、外部から読み込まれるリソースを暗号学的に検証する仕組みです。lottie-player攻撃が特に深刻だった背景には、一般的でありながら危険な次の3つの実践がありました。

1. latestタグの使用

2. integrityチェックの欠如

3. フォールバック戦略の不在

SRIは、期待されるファイル内容の暗号学的ハッシュ値を指定することで機能します。ブラウザは次の処理を行います。

  1. リソースをダウンロードする。
  2. ハッシュ値を計算する。
  3. 指定されたintegrity値と比較する。
  4. 一致しない場合は実行をブロックする。

integrityチェックの検証に失敗した場合、ブラウザはJavaScriptの実行を許可せず、サンプルエラーが表示されます。

Screenshot showing a webpage with accordion UI and browser console errors for invalid SRI hash blocking Bootstrap CSS from CDN

エコシステムへの提言

1. パッケージメンテナー

  • provenance attestationを直ちに有効化する。
  • READMEファイルにprovenance対応状況を明記する。
  • GitHub Actionsを使用して、自動化された検証済みビルドを行う。

2. パッケージ利用者

  • 新しい依存関係を追加する前に、provenance対応状況を確認する。
  • provenanceが有効なパッケージを優先する。TrustyPkgのようなWebサイトを確認し、活動状況やprovenanceなどに基づいて信頼性を把握する。
  • 既存の依存関係についても、provenanceの採用状況を監視する。

3. プラットフォーム提供者

  • NPMレジストリのUIでprovenance対応状況をより見やすくする。
  • provenanceを一括検証するためのツールを提供する。
  • 影響の大きいパッケージにはprovenanceを必須化することを検討する。
  • サーバー側の強制メカニズムを実装する。
  • クライアント側の検証ツールを追加する。

4. NPMレジストリ

  • 組織レベルのprovenance要件を追加する。
  • 人気パッケージに対してattestationの必須化を実装する。
  • provenance検証用のAPIエンドポイントを提供する。
  • パッケージ承認プロセス/ワークフローを提供する。

結論

NPMエコシステムのセキュリティは、世界中の数百万のアプリケーションに影響します。現在、レジストリ側とクライアント側の両方で強制メカニズムが欠如しているため、重大なセキュリティリスクが生じています。provenance attestationは利用可能であるにもかかわらず、それを体系的に強制できないため、エコシステムはサプライチェーン攻撃に対して脆弱なままです。

NPMチームは、サーバー側とクライアント側の両方の強制メカニズムの実装を優先すべきです。それまでは、コミュニティは手動での検証とベストプラクティスに頼らざるを得ません。パッケージメンテナーはprovenance attestationを直ちに有効化し、利用者はより優れたセキュリティ制御と検証ツールを求めるべきです。

NPMのインフラ改善に向けて協力して初めて、より安全なJavaScriptエコシステムを構築できます。エクサフォースでは、オープンソースライブラリが公開プロセスでprovenance attestationを採用できるよう支援することで、その第一歩を踏み出すことに取り組んでいます。

参考文献

[1] @lottiefiles/lottie-playerパッケージに関するセキュリティインシデントの解決

[2] サプライチェーンセキュリティインシデント: LottieFiles NPMパッケージ侵害の分析

[3] 開発者が安全なオープンソースライブラリを利用するためのTrustyPkg Lottie検証データベース

関連記事

理想のSOCチーム。
24時間365日、お客様とともに稼働します。

お客様の環境を一元的かつリアルタイムに把握する4つのエクサボットが、検出、トリアージ、調査、対応をカバーします。プラットフォームを自社で運用することも、エクサフォースに運用を任せることもできます。