AWS CodeArtifactを利用してソフトウェアサプライチェーンのセキュリティを確保しよう
こんにちは!
ダイエットしていますが中々体脂肪率が10%切れない、かめでございます。
今回はソフトウェアサプライチェーンのセキュリティとAWS CodeArtifactに関してご紹介してみたいと思います。
ソフトウェアサプライチェーンのセキュリティの重要性
ソフトウェアサプライチェーンの脆弱性とは
ソフトウェアサプライチェーンの脆弱性とは、ソフトウェア開発および配布プロセスにおいて、外部ライブラリ、依存関係、またはコンポーネントに存在するセキュリティ上の弱点です。これらは攻撃者によって悪用される可能性があり、システムやデータのセキュリティ侵害につながることがあります。
昨今のソフトウェア開発ではnpm, PyPI, Nugetなど、パッケージマネージャを用いてOSSのライブラリを利用することが一般になっていますが、具体的には、これらのパッケージマネージャの提供するパッケージレポジトリ上に、悪意のあるパッケージがアップロードされることにより、自身の開発したソフトウェアに対して悪意のあるコードが仕込まれてしまう、というようなリスクが考えられます。
具体的な脆弱性の例
具体的に、ソフトウェアサプライチェーンの脆弱性を利用した攻撃として、どのような物があるのか見てみましょう。
SolarWindsのサイバー攻撃
2020年に発覚したこの攻撃は、サプライチェーン攻撃の代表例です。攻撃者は、SolarWindsのOrionソフトウェアアップデートメカニズムにマルウェアを挿入し、数千もの企業と政府機関に影響を与えました。
依存関係かく乱攻撃
攻撃者がプライベートレポジトリにあるパッケージと同じ名前のパッケージをパブリックレポジトリに公開し、開発者が誤ってこれらをプロジェクトに組み込むことにより、悪意のあるコードを配布する攻撃です。
脆弱性への対策
こうした脆弱性への対策としては、例えば以下のような対策が有効だと考えられます。
定期的な依存関係の監査と更新
使用されているライブラリやコンポーネントの最新のセキュリティパッチを適用し、脆弱性を定期的にチェックすることが重要です。
ソフトウェア供給網のセキュリティ検証
供給元がセキュリティ基準を満たしていることを確認し、信頼できるソースからのみコンポーネントを取り入れるようにします。
SBOM(Software Bill of Materials)の使用
SBOMは、プロジェクトに含まれるすべてのコンポーネントのリストであり、依存関係の透明性を高め、セキュリティリスクを特定するのに役立ちます。
SBOMに関する補足
上記「脆弱性への対策」でのSBOMに関し、昨今では注目度が上がっているため、補足します。
SBOMとは何か?なぜ重要なのか?
SBOMは、ソフトウェア製品に含まれるすべてのコンポーネントの完全なリストです。これには、オープンソースと商用の両方のライブラリ、パッケージ、モジュールが含まれます。SBOMは、それぞれのコンポーネントのバージョン情報、ライセンス情報、および出所(ソース)情報を提供します。
もう少しかみ砕いて説明すると、「ソフトウェアの食材リスト」のようなもの、と考えることができます。料理を作るときに、どんな材料を使ったか、それらがどこから来たのかを知りたいと思われることが有るかもしれません。SBOMはソフトウェアを構成する「材料」の詳細なリストと捉えることが出来ます。
この「食材リスト」には、ソフトウェアプロジェクトに含まれる全てのコンポーネントが記載されています。これには、使用されているオープンソースのライブラリやパッケージ、さらには商用のソフトウェアパーツまで、プロジェクトを構築するために必要なあらゆる「食材」が含まれます。そして、それぞれの「食材」について、どのバージョンが使われているのか、どこから来たのか(出典)、そしてどんなライセンスで提供されているのかなどの情報が詳しく記載されています。
なぜこれが重要かというと、ソフトウェアを作る際には、様々な外部のコンポーネントを組み合わせています。これらのコンポーネント一つ一つが、最終的なソフトウェア製品の安全性や品質に影響を与える可能性があります。例えば、使われているあるライブラリにセキュリティ上の問題が発見された場合、そのソフトウェアは危険にさらされることになります。
SBOMがあると、ソフトウェアの「材料」を正確に把握できるので、安全なソフトウェアを提供し続けるために、どの「食材」に注意が必要か、どの「食材」を更新する必要があるかが一目でわかります。また、法律や規制で特定の情報の開示が求められた場合にも、SBOMがあれば対応がしやすくなります。
このように、ソフトウェアサプライチェーンのセキュリティという面に対して、SBOMは現在のソフトウェアがどんなものによって構成されているのかを把握することに役立ちます。これに対し、AWS CodeArtifactはソフトウェアサプライチェーンのセキュリティに対してどのように作用してくるのかを見てみましょう。
AWS CodeArtifactの概要
AWS CodeArtifactとは
AWS CodeArtifactは、ソフトウェア開発プロセス中に使用されるコードの依存関係やパッケージを安全に保存、取得、共有するためのフルマネージドなアーティファクトリポジトリサービスです。このサービスを利用することにより、公開されているパッケージマネージャからパッケージを簡単に取得・管理し、プロジェクト間で共有できるようになります。また、セキュアなアクセスと統合、依存関係の自動解決を提供し、ソフトウェアビルドと配布プロセスの効率化とセキュリティ向上を目的としています。
2024/2月時点では、以下のパッケージマネージャを取得元(パブリックアップストリームリポジトリ)として指定することが出来ます。
動作イメージとしては、パッケージマネージャクライアント(npmコマンド等)とパブリックレポジトリ(npmレポジトリ等)の間にAWS CodeArtifact が入り、プロキシのような形で動作することになります。
AWS CodeArtifactがソフトウェアサプライチェーンセキュリティにどう貢献するか
AWS CodeArtifactは、ソフトウェアサプライチェーンセキュリティに複数の点で貢献すると考えられます。以下は、AWS CodeArtifactがサプライチェーンセキュリティにどのように貢献するかの具体例です。
依存関係のセキュアな管理
AWS CodeArtifactを使用することで、開発プロジェクトにおける依存関係を一箇所でセキュアに管理できます。依存関係が中央管理されることで、不正なパッケージの挿入や脆弱性のあるバージョンの使用を防ぐことができ、サプライチェーン全体のセキュリティが強化されます。
パッケージの承認
CodeArtifact API と AWS EventBridgeを利用して自動ワークフローを構築することにより、使用するパッケージを承認することが出来ます。これにより、前述の依存関係かく乱攻撃に対する耐性を向上させることが出来ます。
アクセスコントロール
AWS Identity and Access Management (IAM)を利用することにより、アーティファクトへのアクセスを細かくコントロールできます。これにより、認証されたユーザーのみが特定のパッケージにアクセスでき、不正アクセスのリスクを軽減します。
VPCリソースのインターネットからの隔離
AWS CodeArtifact用のインターフェースVPCエンドポイントを利用することで、EC2やECSタスク等のVPCリソースがCodeArtifactで管理されているパッケージにアクセスすることが出来ます。これにより、VPCリソースがインターネット経由でパブリックリポジトリにアクセスすることを防ぐ事が出来ます。
AWS CodeArtifactを利用したセキュリティ強化
AWS CodeArtifactリポジトリの作成
今回は、CDKを用いて環境を構築することにします。今回の対象となるパブリックリポジトリは、npm としています。
まずは以下のコマンドにてこちらのGitリポジトリをクローンします。
git clone https://github.com/tak-kam/codeartifact-cdk-sample.git
Gitリポジトリをクローン出来たら、以下のコマンドを実行することで、CodeArtifactリポジトリをAWS上にデプロイします。事前にAWS CLIプロファイルや認証情報の設定等が必要な方は、実施後に以下のコマンドを実行ください。
cd codeartifact-cdk-sample
npm install
npx cdk deploy --require-approval never
デプロイが完了したら、マネジメントコンソールのCodeArtifactのリポジトリを見てみましょう。ドメイン名が my-domain
、リポジトリ名が my-repo
のリポジトリが作成されているかと思います。
CodeArtifactリポジトリを利用するための設定
デプロイされたCodeArtifactリポジトリを利用するように、ローカルのnpmコマンドに設定を行います。まずは、作成されたCodeArtifactリポジトリをクリックし、「接続手順の表示」ボタンをクリックします。
表示されたダイアログにて、オペレーティングシステムを自分の環境にあわせて設定し、パッケージマネージャーはnpmを選択します。その後、下部に表示されているコマンドをコピーし、ターミナルで実行してください。
以上でCodeArtifactリポジトリを利用するための設定は終了になりますが、この設定自体の有効期限は12時間となっているようですので、失効した場合は再度同じ手順を実施してください。
AWS CodeArtifactの利用
それでは、実際にCodeArtifactリポジトリを利用できているか確認してみましょう。先ほどクローンしたGitリポジトリのディレクトリにて、以下のコマンドでnpmからパッケージを取り直してみましょう。
# node_modulesの削除
rm -rf node_modules
# npmキャッシュの削除
npm cache clean --force && rm -rf ~/.npm
# パッケージ再取得
npm install
上記コマンド実行後、先ほどのCodeArtifactパッケージ画面を更新すると、パッケージが追加されていることが判ると思います。この中から、パッケージのプレフィックス入力欄に aws
と入力してみてください。そうすると、aws-cdk
のバージョン2.114.1 が表示されているかと思います。これは、最新バージョンとは表示されていますが、package.json
に定義されている aws-cdk
をCodeArtifactリポジトリにて取得し、保持しているものの最新バージョンという意味で、npm によって公開されているものの最新バージョンと言うわけではありません。
2024/2月時点では aws-cdk
の最新バージョンはもっと先に進んでいますので、最新バージョンを取得するために、以下のコマンドを実行してみましょう。
npm install aws-cdk@latest aws-cdk-lib@latest
再度CodeArtifactパッケージ画面を更新すると、最新バージョンが変わっていることが判ります。(記事執筆時点での最新版は2.126.0でした)
ここで、aws-cdk
パッケージを選択してみると、CodeArtifactリポジトリにて保持している aws-cdk
のバージョンが、2.126.0 と 2.114.1 となっていることが判ります。
このようにして、CodeArtifactを用いてプライベートなパッケージリポジトリを簡単に構築することができました。
npmコマンドのリポジトリをデフォルトに戻す方法
先ほど紹介した手順を実行した場合、npmコマンドのデフォルトリポジトリであるnpmjsが利用できなくなっています。デフォルトリポジトリに戻したい場合は、以下のコマンドを実行してください。
rm ~/.npmrc
より実践的なAWS CodeArtifactの活用方法
アップストリームリポジトリからのダウンロード禁止設定
ソフトウェアサプライチェーンのセキュリティ向上のため、利用できるパッケージを制限することも出来ます。クライアントが好き勝手に新たなパッケージを利用することを禁止するため、以下の設定を行ってみましょう。
今回は簡単な方法として、アップストリームリポジトリを削除することでアップストリームリポジトリからの新規パッケージダウンロードを禁止してみます。先ほどクローンしたCDKのコードの lib/codeartifact-cdk-sample-stack.ts
を開き、15行目を以下のように変更し、アップストリームリポジトリを削除します。
// 変更前
externalConnections: ["public:npmjs"],
// 変更後
externalConnections: [],
ファイル保存後、以下のコマンドを実行して再度デプロイします。
cdk deploy --require-approval never
この設定により、アップストリームリポジトリからの新規パッケージ(新しいバージョン含む)のダウンロードが出来なくなっていますので、動作確認をしてみます。
package.json
に記載されているTypescriptのバージョンは5.2.2ですが、以下のコマンドを実行して、Typescriptのバージョンを更新してみましょう。
npm install --dev typescript@5.3.3
以下のようなエラーが出て更新出来ませんでした。新しいバージョンのパッケージがダウンロードされるのが期待通りブロックされていることが判ります。
> npm ERR! notarget No matching version found for typescript@5.3.3.
> npm ERR! notarget In most cases you or one of your dependencies are requesting
> npm ERR! notarget a package version that doesn't exist.
再度ダウンロード可能にするためには、アップストリームリポジトリを再度設定してデプロイしなおすと、正常にバージョンアップできることが確認出来ると思います。
// 変更前
externalConnections: [],
// 変更後
externalConnections: ["public:npmjs"],
まとめ
本記事では、AWS CodeArtifactを利用してどのようにソフトウェアサプライチェーンのセキュリティを向上させることが出来るのか、イメージをご紹介しました。最後の方に紹介した、アップストリームリポジトリからのダウンロード禁止設定だけだと、新たなパッケージのダウンロードが一律禁止されてしまうため、実用的に厳しい部分もあるかと思います。そうなった場合に、前述のCodeArtifact API と AWS EventBridgeを利用した自動ワークフローを構築することで効率化が図れるかと思いますが、それはまた別の機会でご紹介したいと思います。