依存関係管理のベスト プラクティス
Google Cloud Japan Team
※この投稿は米国時間 2021 年 7 月 28 日に、Google Cloud blog に投稿されたものの抄訳です。
この記事では、脆弱性モニタリング、アーティファクト検証、依存関係フットプリントを削減して再現可能にするためのステップなど、アプリケーションの依存関係を管理するための一連のベスト プラクティスについて説明します。
各プラクティスの内容は、言語エコシステムと使用するツールによって異なりますが、一般原則はどの場合にも当てはまります。
依存関係管理は、安全で信頼できるソフトウェア サプライ チェーンを作成するための 1 つの要素にすぎません。他のベスト プラクティスについては、次のリソースをご覧ください。
バージョンの固定
バージョンの固定とは、アプリケーションの依存関係のバージョンを極めて限られたバージョンに制限することです。1 つのバージョンに絞り込むのが理想的です。
依存関係のバージョンを固定すると、アプリケーションがある時点で凍結されるという副作用が起きます。バージョンの固定は、再現性の面からはおすすめしますが、セキュリティの修正、バグの修正、全般的な改良のために依存関係のリリースが新しくなったときの更新を受け取れないという欠点があります。
この状況は、自動化された依存関係管理ツールをソース コントロール リポジトリに適用することで軽減できます。ツールで依存関係に新しいリリースがあるかモニタリングし、要件ファイルを更新して必要に応じて新しいリリースにアップグレードします。多くの場合、新しいリリースには変更ログ情報や補足情報などが含まれます。
シグネチャとハッシュの検証
所定のリリースのパッケージに対し、所定のアーティファクトが意図したとおり実際にインストールされているか確認する場合、アーティファクトの信頼性を検証するために、さまざまなセキュリティ レベルの複数のメソッドを利用できます。
ハッシュ検証を使用すると、所定のアーティファクトのハッシュと、アーティファクト リポジトリから提供される既知のハッシュを比較できます。ハッシュ検証を有効にすることで、依存関係が中間者攻撃やアーティファクト リポジトリの侵害を通じて、別のファイルに不正に置き換えられることがなくなります。この機能を使用する場合には、検証時(または最初の取得時)にアーティファクト リポジトリから受け取るハッシュは侵害されていないということを信頼する必要があります。
シグネチャ検証を実施すると、検証プロセスのセキュリティが高まります。アーティファクトはアーティファクト リポジトリ、ソフトウェアの管理者、またはこの両者によって署名されます。sigstore などの新しいサービスの導入で、管理者はソフトウェア アーティファクトへの署名が簡単になり、消費者にとってもシグネチャの検証が簡単になります。
ロックファイルとコンパイルされた依存関係
ロックファイルは完全に解決された要件ファイルで、任意のアプリケーションに対してどのバージョンの依存関係をインストールすべきかを、正確に指定します。ロックファイルは通常、インストール ツールによって自動的に生成され、バージョンの固定およびシグネチャまたはハッシュの検証を、アプリケーションの完全依存関係ツリーと結合します。
完全依存関係ツリーは、最上位の依存関係にインストールされる、すべての依存関係を「コンパイル」または完全に解決することで生成されます。完全依存関係ツリーは、すべてのサブ依存関係、その依存関係、以降のスタックを含むアプリケーションのすべての依存関係が、ロックファイルに組み込まれることを意味します。これらの依存関係だけがインストールされるので、ビルドの再現性が高まり、複数のインストール間での整合性が向上します。
プライベートの依存関係とパブリックの依存関係の混在
最先端のクラウドネイティブ アプリケーションは多くの場合、オープンソースのサードパーティ コードとクローズド ソースの内部ライブラリの両方に依存します。複数のアプリケーション間でビジネス ロジックを共有する必要があり、しかも外部ライブラリと内部ライブラリの両方をインストールするために同じツールを再利用したい場合、クローズド ソースの内部ライブラリは特に有効です。Artifact Registry などのプライベート リポジトリを使用すると簡単にできます。
ただし、プライベートの依存関係とパブリックの依存関係を混合する場合、「依存関係の混同」攻撃に注意が必要です。内部プロジェクトと同じ名前のプロジェクトをオープンソース リポジトリに公開すると、構成に誤りのあるインストーラを利用して、内部パッケージの上に悪意のあるライブラリを不正にインストールするという攻撃方法を取れる可能性があります。
「依存関係の混同」攻撃を防ぐための手順は、次のようにいくつもあります。
依存関係のシグネチャとハッシュを検証するため、これらをロックファイルに組み込む
サードパーティの依存関係のインストールと内部依存関係のインストールを 2 つのステップに分ける
プライベート リポジトリに必要なサードパーティの依存関係を、手動またはプロキシを介した pull で明示的にミラーリングする
未使用の依存関係の除外
リファクタリングが発生し、ある日に必要だった依存関係が、次の日には不要になることがあります。アプリケーションと同時に、使用されなくなった依存関係をインストールしてしまうと、依存関係のフットプリントが増し、その依存関係の脆弱性によって不正使用される可能性も高まります。
一般的な対処方法としては、アプリケーションをローカルで実行し、開発プロセス中にインストールしたすべての依存関係をアプリケーションの要件ファイルにコピーしてから、そのファイルをデプロイします。この方法によって正しく動作することが保証されていますが、本番環境に必要のない依存関係が導入される可能性もあります。
一般的に、新しい依存関係をアプリケーションに追加すると、開発者が完全には制御できないコードが導入される可能性があるので注意してください。依存関係が実際に使用またはインポートされているか確認するため、要件ファイルを監査するツールを使用すると、定期的な lint チェックとテストのパイプラインにこの確認作業を組み込むことができます。
脆弱性スキャン
依存関係のいずれかに脆弱性が認められた場合、通知はどのように行なわれるのでしょうか。依存しているサードパーティ ソフトウェアの脆弱性データベースすべてを積極的にモニタリングされてはいないでしょう。また、どのサードパーティ ソフトウェアに依存しているかを信頼できる精度で確かめることは不可能な場合がほとんどでしょう。
脆弱性スキャンを使用すると、依存関係がアプリケーションに脆弱性をもたらしているかどうか、一貫して自動的に評価を行えます。脆弱性スキャンツールはロックファイルを使用して、依存するアーティファクトを正確に見極め、新たな脆弱性が表面化したときにデベロッパーに通知します。アップグレード方法を提案することもあります。
Container Analysis などのツールの利用で、コンテナ イメージに対する脆弱性スキャンを広範囲に行えます。同時に Java パッケージのスキャンなどの言語アーティファクトのスキャンも行います。この機能を有効にすると、コンテナ イメージのパッケージに関する脆弱性が識別されます。イメージが Artifact Registry にアップロードされると、イメージがスキャンされ、イメージを push してから最大 30 日間、新しい脆弱性を検出するためにデータが継続的にモニタリングされます。
-シニア デベロッパー アドボケイト Dustin Ingram