クラウド環境
公開状態のコンテナレジストリ:膨大な情報の山に潜むリスク
公開状態のレジストリに潜むセキュリティリスクに踏み込み、攻撃者に不正アクセスされる可能性のあるファイルやデータの種類、およびその影響を分析しました。
前回の記事では、外部公開されたレジストリ(本稿では「オープンレジストリ」と呼ぶ)に潜むリスクに着目し、攻撃者に不正利用されかねないデータが多量に公開されている実態について解説しました。
レジストリとコンテナランタイム間の通信
コンテナレジストリは、一般にコンテナイメージを所蔵、分類した図書館のようなものと見なされがちです。しかし、実際に各種システムがこうしたレジストリ内のイメージを取得(プル)する仕組みを理解するには、API(Application Programming Interface)の働きに着目する必要があります。コンテナを生成する際には、APIリクエストをレジストリ側に送信することで、イメージをプルできます。こうして取得されたイメージには、アプリケーションファイルや環境変数、設定ファイル、ライブラリなどが格納されています。本イメージは、さらにランタイム側に転送されます。次いで、ランタイムがそれを使用してコンテナを作成します。
オープンレジストリの実態を探る
発見されたオープンレジストリを詳細に調べた結果、量と機密性の双方で重大なインパクトを持つデータが発見されました。以降、その内容の分析結果を示すとともに、安全に管理されていないオープンレジストリの危険性について解説します。
はじめに、これら私有レジストリの一部は、「バージョニングキーパー(製品開発用に、同一イメージのさまざまなバージョンに対するバックアップを保持する)」として利用されていることが判明しました。前回の報告では、9.31 TBに及ぶイメージがダウンロードされた他、197個の独立したレジストリ、20,503個のイメージがダンプされた旨を述べました。しかし、これらの数値は、バージョニング機能を有するリポジトリ内から直近の3バージョンを取った結果に過ぎません。実際の数値ははるかに大きいものと予想されます。
これほど大規模に及ぶデータのダウンロードや保存には相応の準備が必要となりましたが、何よりも、そこから機密情報を選別する作業は、単調で、かつ長い時間を要するものでした。はじめに、ネスト化されたアーカイブの階層をまたいで機密情報を含むイメージを探し出すため、正規表現マッチングによる検索を行いました。次に、コンテナイメージの中から、稼働しているプロジェクトやコンテナのセキュリティに影響を及ぼしうるファイルを見つけ出すため、ツールによる検索を行いました。この際、直接的なリーク(情報流出)となるファイルは対象外としました。以降、検索の内容や結果について、さまざまな観点を交えて解説します。
コンテナイメージに対する分析の一環として、今回は使用されているベースイメージにも注目しました。ベースイメージはコンテナのバックボーンに相当し、オペレーティングシステムとしての中核機能に加え、コンテナ化されたアプリケーションの稼働環境を提供します。また、コンテナのセキュリティ、処理速度、パフォーマンスに関わる総合的な役割も担います。
特定されたベースイメージの中では、Alpine、Debian、Ubuntuが全体の80%以上を占めました。これらは確かに好まれていますが、安全で、かつ本番環境にも十分に耐えうるアプリケーションをビルドできるかどうかについては、検討の余地があります。
軽量型のAlpineは、コンテナ容量を最小限に抑え込みたい場合によく使用されます。余分な機能を削ぎ落として小型化されているため、シンプルなアプリケーションに適しています。しかしこのことは、より複雑で重要度の高いアプリケーションに期待されるセキュリティや機能が十分に備わっていない可能性を示唆しています。今回確認されたAlpineによるベースイメージの大半は、本稿執筆時点ですでに古いバージョン、または脆弱性を含むバージョンであり、最新バージョンはわずか27件に留まりました。
一方、重量型のDebianやUbuntuは、より高度な機能を備え、複雑なアプリケーションにも対応可能です。しかし、この利便性にはリスクが伴います。ベースイメージに追加されるさまざまな機能のうち、その1つでも脆弱性があれば、そこが攻撃の侵入経路に利用される可能性があります。アプリケーションの開発者は、これらベースイメージが抱える依存関係の内容やその扱い方に十分な注意を払う必要があります。
別の発見事項として、今回調査したオープンレジストリから、Distrolessのイメージはほとんど発見されませんでした。Distrolessは軽量でありながらもセキュリティ面に配慮した作りとなっています。アプリケーションの稼働に最低限必須となる機能を提供する一方、容量の肥大化に繋がる余分な機能は削ぎ落とされています。これにより、セキュリティ上の弱点を生み出す要素が削減されます。こうしたDistrolessのメリットについては前回の比較調査でも触れましたが、今回の調査結果より、あまり利用されていない実態がうかがえます。
ソースコードや機密情報の流出
今回の調査で浮上したもう1つの重大な懸念事項は、ソースコードの流出です。ソースコードを通してセキュリティ関連の重要情報が攻撃者に盗み取られた場合、有効なトークンや認可用プロトコル「OAuth」のシークレットが偽造され、システムやデータに不正アクセスされる可能性があります。さらに攻撃者は、アプリケーションのユーザになりすまして不正な活動を展開し、被害を拡大させる恐れがあります。また、ソースコードの流出は、ビジネス面でのリスクを生み出します。ソースコードを通して企業や組織による私有のアルゴリズムや業務ロジックが漏洩すると、競合他社に利用されて不利な状況に追い込まれる他、業務を妨害されるケースも考えられます。
本調査で上がった最も重大な懸念事項は、ファイルシステムやコンテナイメージのメタデータに格納された機密情報の流出です。このメタデータは、環境ディレクティブによって環境変数を設定するものです。以降、調査対象のイメージから発見された機密情報について、種別ごとに解説します。
S3の鍵データ:これらの鍵を入手した攻撃者は、クラウドストレージ・バケットにアクセスし、そこで追加の機密情報を窃取、または不正なコンテンツをホストする可能性があります。
CSPアクセス鍵:これらの鍵を入手した攻撃者は、クラウドサービスプロバイダ(CSP:Cloud Service Provider)にアクセスし、標的企業の資金を喰い潰してリソースを不正利用する他、追加のデータに不正アクセス、または企業のクラウド環境を攻撃の踏み台として利用する可能性があります。
データベースの認証情報:これらの認証情報を入手した攻撃者は、データベースにアクセスし、データを窃取、改変、削除する可能性があります。
アプリケーション認証情報:これらの認証情報を入手した攻撃者は、プライベートなアプリケーションにアクセスし、正規ユーザになりすまして不正な活動を行う他、追加の機密情報を窃取する可能性があります。
JSON Webトークン(JWT):これらの認証関連データを入手した攻撃者は、システムやデータに不正アクセスする可能性があります。
以降、上図に示すファイル種別ごとに、その内容や、不正アクセスされた場合に生じるセキュリティリスクについて解説します。
.env
.envは、本調査で確認されたファイル種別の中で最も機密性の高いものであり、プログラミング環境において環境変数を格納する目的で広く使用されています。ファイル内容として、データベースの認証情報やAPI鍵など、アプリケーションの稼働に必要な機密情報が含まれている場合もあります。本来、特別な理由がない限り、こうした機密情報をアプリケーションのソースコード中にハードコーディングすべきではありません。
.envファイルが流出した場合、上述した各種リソースへのアクセス権が攻撃者側に掌握され、データベースの不正アクセス、APIの不正利用に至る可能性があります。また、標的のアプリケーションのみに留まらず、クラウドバケットやリモートデータベースなどの関連サービス上で不正な活動が行われる事態も考えられます。被害の深刻度は、盗み出された認証情報が持つ権限によって変化し、情報窃取からサービス障害、さらにはインフラにまで及ぶと考えられます。
Dockerfile
Dockerfileは、Docker用イメージやコンテナのバックボーンとして機能します。Dockerは、本ファイルに記載の指示情報に基づいてイメージのビルドやコンテナの起動を行います。指示情報の内容として、使用するベースイメージ、ビルド時に実行するコマンド、公開ポートの番号、イメージ内にコピーするファイルとディレクトリ、イメージに即したコンテナが始動した際に実行するコマンドなどが挙げられます。Dockerfileには、API鍵やデータベースの認証情報、環境変数などの機密情報が含まれる場合もあります。
本ファイルが流出した場合、ソフトウェアスタックの中で使用される古くて脆弱なベースイメージや依存関係など、セキュリティ的に弱い部分を攻撃者側に特定される可能性があります。この他、Dockerイメージの内部構造を解析されて重要なファイルやディレクトリを特定される他、アプリケーションの起動コマンドや公開ポートを知られる事態も考えられます。
application_default_credentials.json
本ファイルは、他のクラウドプラットフォーム用サービスの環境に特有のものです。ファイル内容として、サービスアカウントの認証情報が記載されます。Google Cloud Platform(GCP)で稼働するアプリケーションは、この認証情報を用いることで、他のGCPサービスとやり取りできるようになります。認証情報の内容として、アカウントの種別、クライアントのIDとシークレット、認証用URI、トークンURL、認証プロバイダのx509証明用URL、クライアントのx509証明用URLなどが挙げられます。
本ファイルが流出した場合、当該クラウドプラットフォームに関連するサービスが不正アクセスされる可能性があります。これにより、GCPサービスに格納された機密情報への不正アクセス、GCPリソースの不正な改変、サービスの開始と終了などの活動が行われる恐れがあります。被害の深刻度は、侵害されたサービスアカウントの権限設定によって変化し、情報窃取からサービス障害、さらにはインフラ乗っ取りにまで及ぶと考えられます。
manifest.yml
本ファイルは、特に「サービスとしてのプラットフォーム(PaaS:Platform-as-a-Service)」の上で稼働するクラウドアプリケーションに用いられます。ファイル内容として、アプリケーション構成、サービス、環境固有の設定などが記載されます。より具体的には、インスタンスの個数、インスタンス毎のメモリ制限、アプリケーションのルート(URL)、アプリケーションに紐付けるサービスなどが挙げられます。
本ファイルが流出した場合、アプリケーションの依存関係やサービス名、各種メタデータが攻撃者側に知られ、そこからアプリケーションの構成や脆弱性を特定される可能性があります。また、アプリケーションの構造や依存関係、環境設定を特定され、利用中のプラットフォームに効果的な攻撃を展開される恐れがあります。
id_rsa
本ファイルは通信プロトコル「SSH(Secure Socket Shell)」の公開鍵認証に使用され、SSHの秘密鍵を内容として含みます。一般に秘密鍵は外部に漏れないようにユーザ側で厳重に保管されるのに対し、公開鍵は、ユーザが接続するシステム側に配備されます。ユーザがシステムに接続する際、対象システムは公開鍵によってチャレンジ・メッセージを暗号化し、ユーザ側に送付します。これに対してユーザのSSHクライアントは、秘密鍵によってメッセージを復号し、結果をシステム側に送信します。システムはその内容をチェックし、正しい場合は、当該ユーザからのアクセスを許可します。
本ファイルが流出した場合、対応する公開鍵を配備するあらゆるシステムが、不正アクセスのリスクに晒されます。こうした状況を引き金として、情報窃取、システム障害、さらなるネットワーク侵入に発展する可能性があります。さらに、盗まれたSSH鍵に対応するユーザの権限によっては、権限昇格や、ネットワーク上の水平移動・内部活動が実行される恐れもあります。
Jenkinsfile
ファイル「Jenkinsfile」は、オープンソースによる自動化サーバ「Jenkins」において、CI/CD(Continuous Integration and Continuous Delivery and Continuous Deployment:継続的なインテグレーションとデリバリおよびデプロイ)のパイプラインを定義するために使用されます。Jenkinsは、本ファイルに記載の指示情報に基づいてアプリケーションをビルド、テスト、デプロイします。指示情報の内容として、パイプラインのステージ、各ステージ内で実行するステップ、ステップを実行するノード、その他さまざまな環境変数や認証情報が挙げられます。
本ファイルが流出した場合、ビルドやデプロイに関わる機密情報が攻撃者側に知られる可能性があります。機密情報の内容として、ソースコード用リポジトリの場所、ビルドやテストに際して実行するコマンド、デプロイサーバの場所、これらリソースにアクセスするための認証情報などが挙げられます。当該情報を入手した攻撃者は、パイプライン内に不正なコードを埋め込む他、アプリケーションのデリバリ工程を侵害、またはソースコードやデプロイサーバに不正アクセスする恐れがあります。
package-lock.json
本ファイルはNode.jsのアプリケーションに使用されるものであり、ファイル「package.json」が存在する状態でNPM(Node Package Manager)のインストールコマンドを実行した際に、自動作成されます。ファイル内容として、アプリケーションの依存関係がインストールされた際に、そのツリー情報が記録されます。その中には、各依存関係に対応するバージョン情報なども含まれます。
本ファイルが流出した場合、依存関係のバージョン情報が攻撃者側に知られる可能性があります。本情報を入手した攻撃者は、そのバージョンに特有のセキュリティ脆弱性を突いた攻撃に及ぶ恐れがあります。この他、アプリケーションが用いる全依存関係の名前やバージョン、相互依存関係を含め、さまざまな構造情報が攻撃者側に知られる事態も考えられます。
azure-pipelines.yml
本ファイルは、Azure DevOpsのアプリケーションで利用されます。ファイル内容として、ビルドやデプロイのパイプラインを定義する指示情報が記載されます。Azure Pipelineは、この指示情報に基づいてアプリケーションのビルド、テスト、デプロイを行います。指示情報の内容として、パイプラインを構成するステージ、各ステージ内で実行するジョブ、各ジョブ内で実行するステップ、その他さまざまな変数やリソースが挙げられます。
本ファイルが流出した場合、ビルドやデプロイの工程に関する機密情報が攻撃者側に知られる可能性があります。具体的には、ソースコードリポジトリの場所、アプリケーションのビルドやテスト時に使用するコマンド、デプロイ用サーバの場所、これらリソースにアクセスするための認証情報などが挙げられます。当該情報を入手した攻撃者は、パイプライン内に不正なコードを埋め込む他、アプリケーションのデリバリ工程を損害、またはソースコードやデプロイ用サーバに不正アクセスする恐れがあります。
ansible.cfg
本ファイルはAnsibleのアプリケーションにおいて、コマンドラインツールや「Ansible Playbook」を設定するために使用されます。ファイル内容として、接続種別、権限昇格、複製(fork)、タイムアウト、持続的接続、プラグインのパスなどが挙げられます。
本ファイルが流出した場合、リモートシステムや権限昇格などに関する機密情報が攻撃者側に知られる可能性があります。当該情報を入手した攻撃者は、Ansibleのシステムや、Ansibleの管理下にあるシステムを不正利用する恐れがあります。被害の深刻度は、侵害されたAnsibleの設定やその権限に応じて変化し、不正なコマンド実行から情報窃取、さらにはシステム障害に及ぶと考えられます。
service.yaml
本ファイルは、Kubernetesの「サービス」を定義するために利用されます。Kubernetesのサービスは、「ポッド」の論理セットや、それにアクセスする際のポリシーを定義し、これを抽象的に扱えるようにします。ポッドは、Kubernetesのモデル上で最小単位のオブジェクトに相当します。ファイル「service.yaml」の内容として、サービス種別、公開ポート、トラフィックを受信するポッドの選択方式、接続先ポットを固定する設定「Session Affinity」などが挙げられます。
本ファイルが流出した場合、Kubernetesのサービスに関する内部構造が攻撃者側に知られる可能性があります。当該情報を入手した攻撃者は、アプリケーションのアーキテクチャを特定し、サービスやその管理下にあるポッドの脆弱性を不正利用する他、サービスを侵害する恐れがあります。
docker-compose.yml
本ファイルは、マルチコンテナによるDockerアプリケーションの定義や起動をサポートする「Docker Compose」に使用されます。ファイル内容として、Dockerアプリケーションのサービス、ネットワーク、ボリューム情報などがYAML形式で記載されます。その中には、稼働するコンテナ、作成するネットワーク、マウントするボリューム、その他さまざまな環境変数が含まれます。
本ファイルが流出した場合、Docker環境の内部構造が攻撃者側に知られる可能性があります。当該情報を入手した攻撃者は、アプリケーションのアーキテクチャを特定した上で、コンテナやネットワーク、ボリュームに潜む脆弱性を不正利用、またはアプリケーションを侵害する恐れがあります。
.gitlab-ci.yml
本ファイルは、GitLab CI/CDにおいて、アプリケーションのビルド、デプロイ用パイプラインを定義するために使用されます。GitLab Runnerは、本ファイルに記載の指示情報に基づいてアプリケーションのビルド、テスト、デプロイを行います。指示情報の内容として、パイプラインのステージ、各ステージ内で実行するジョブ、各ジョブ内で実行するスクリプト、その他変数やアーティファクトが含まれます。
本ファイルが流出した場合、ビルドやデプロイ工程に関する機密情報が攻撃者側に知られる可能性があります。具体的にはソースコードリポジトリの場所、アプリケーションのビルドまたはテスト時に使用するコマンド、デプロイ用サーバの場所、これらリソースにアクセスするための認証情報などが挙げられます。当該情報を入手した攻撃者は、パイプライン内に不正なコードを埋め込む他、アプリケーションのデリバリ工程を侵害、またはソースコードやデプロイ用サーバに不正アクセスする恐れがあります。
.dockerignore
本ファイルは、Dockerにおいて、イメージのビルド対象外とするファイルやディレクトリのパターンを指定するために使用されます。「.dockerignore」はGitの「.gitignore」と同様に機能しますが、前者は対象ファイルをビルドコンテキストから除外するのに対し、後者はバージョンコントロールから除外する点で、差異があります。
本ファイルが流出した場合、Dockerイメージの構造に関する機密情報が攻撃者側に知られる可能性があります。攻撃者は、当該情報を元手に、重要なファイルやディレクトリの格納場所、アプリケーションのソースコードや依存関係を特定しようとする可能性があります。
server.js
本ファイルは多くの場合、Node.js用アプリケーションのメイン・エントリポイントとして機能します。ファイル内容として、サーバを起動するためのコードや、アプリケーションのルーティングに関する情報が記載されます。
本ファイルが流出した場合、アプリケーションの構造や機能に関する機密情報が攻撃者側に知られる可能性があります。具体的には他のソースファイルの格納場所、アプリケーションが公開するエンドポイントやルーティング設定、使用するミドルウェアなどが挙げられます。当該情報を入手した攻撃者は、コード内の脆弱性を突いてアプリケーションの動作を侵害する他、アプリケーションデータに不正アクセスする恐れがあります。
.npmrc
本ファイルは、Node.jsのアプリケーションにおいてNPMを設定するために使用されます。ファイル内容として、レジストリ、キャッシュ、プレフィクス、NPMの動作に関する設定が記載されます。この中には、プライベートレジストリやスコープ付きパッケージの認証トークンも含まれます。
本ファイルが流出した場合、プライベートレジストリの認証情報や各種設定が攻撃者側に知られる可能性があります。当該情報を入手した攻撃者は、NPMの環境を不正利用し、プライベートなパッケージに不正アクセスする他、アプリケーションの動作を侵害する恐れがあります。
main.yml
本ファイルは多くの場合、GitHub Actionsにおいて、アプリケーションのワークフローを定義するために使用されます。GitHubは、本ファイルに記載の指示情報に基づいてアプリケーションをビルド、テスト、デプロイします。指示情報の内容として、ワークフローをトリガーするイベント、実行するジョブ、各ジョブ内で実行するステップ、さまざまな環境変数やシークレットなどが挙げられます。
本ファイルが流出した場合、ビルドやデプロイの工程に関する機密情報が攻撃者側に知られる可能性があります。具体的にはソースコード用リポジトリの場所、アプリケーションのビルドやテスト時に実行するコマンド、デプロイ用サーバの場所、これらリソースにアクセスするための認証情報が挙げられます。当該情報を入手した攻撃者は、ワークフロー内に不正なコードを埋め込む他、アプリケーションのデリバリ工程を侵害、またはソースコードやデプロイ用サーバに不正アクセスする恐れがあります。
.travis.yml
本ファイルは、Travis CIにおいて、アプリケーションのビルドやテスト工程を定義するために使用されます。Travis CIは、本ファイルに記載の指示情報に基づいてアプリケーションをビルド、テスト、デプロイします。指示情報の内容として、言語、言語のバージョン、利用するサービス、実行するスクリプト、さまざまな環境変数やシークレットなどが挙げられます。
本ファイルが流出した場合、ビルドやテスト工程に関する機密情報が攻撃者側に知られる可能性があります。具体的にはソースコード用リポジトリの場所、アプリケーションのビルドやテスト時に実行するコマンド、デプロイ用サーバの場所、これらリソースにアクセスするための認証情報が挙げられます。当該情報を入手した攻撃者は、プロセス内に不正なコードを埋め込む他、アプリケーションのデリバリ工程を侵害、またはソースコードやデプロイ用サーバに不正アクセスする恐れがあります。
Vagrantfile
本ファイルは、Vagrantにおいて仮想マシンを設定するために利用されます。ファイル内容として、仮想マシンの作成、設定、プロビジョニング、制御に必要な指示情報が記載されます。この中には、使用するベースボックス(Base Box)、プロバイダ、ネットワーク設定、同期化フォルダ、プロビジョナー、さまざまな環境変数やシークレットも含まれます。
本ファイルが流出した場合、仮想環境に関する機密情報が攻撃者側に知られる可能性があります。当該情報を入手した攻撃者は、仮想マシンの脆弱性を不正利用する他、仮想環境の動作を侵害、または仮想マシンに不正アクセスする恐れがあります。
自己運用型レジストリとクラウドサービス型レジストリの比較
本調査で発見されたデータの規模を踏まえると、自己運用によるレジストリとクラウドサービスによるレジストリのどちらが安全なのか、という疑問が挙がります。もちろん、どちらにも長所と短所があります。自己運用であれば、より柔軟なアクセス制御が可能となり、ストレージやイメージの格納場所に関する選択肢も広がるでしょう。しかし、このことは同時に、レジストリのセキュリティ設定やサーバの管理を、自分自身の手で行う必要があることを示唆しています。
一方、クラウドサービスでは、サーバ管理やセキュリティ関連の機能が事前に組み込まれているため、利便性の面で優れています。しかし、そのトレードオフとして、設定や制御の柔軟性については自己運用型レジストリに劣ります。
利便性の裏で生じるリスク
アプリケーションを個別のワークロードにデプロイする従来型モデルと、コンテナを用いる近代型モデルの間には、明確な差異が存在し、セキュリティ面で大きな影響を及ぼします。アプリケーションの開発やデプロイ、セキュリティ対策においては、その内容を正しく理解することが極めて重要です。
コンテナを利用せずにアプリケーションサービスを複数のワークロードに分散させるインフラ構成では、各サービスが固有のワークロード内で稼働し、他のサービスから分離されています。このワークロードとしては、物理的なサーバと仮想マシンの双方が含まれます。こうした分離モデルでは、ある一定のセキュリティが確保されます。理由として、仮に攻撃者がアプリケーションの全サービスにアクセスしたい場合、その全ワークロードを侵害する必要があります。そうしない限り、攻撃対象の完全な掌握には至りません。全てのワークロードを侵害するには相当の時間が必要であり、さらに高度なスキルやリソースも求められるため、攻撃者にとっては敷居の高いタスクと言えるでしょう。
しかし、こうした状況はコンテナの登場によって一変しました。アプリケーションのあらゆるサービスが単一パッケージに集約される結果、安定した環境が用意されると同時に、ポータビリティや拡張性、効率性が向上しました。このマルチ分離機能により、コンテナは暗黙的に安全なものと見なされやすく、専用のワークロード外で利用されるケースさえ見られます。コンテナは確かにさまざまな恩恵をもたらしますが、一方で、そこに潜むセキュリティリスクが見逃される傾向にあります。
コンテナによるエコシステムのセキュリティは、DevOpsの業務やその形態に大きく依存します。問題を引き起こしがちな状況として、コンテナアプリケーションのビルドにコンテナを利用する、ビルドを成功させるためにシークレットをハードコーディングする、それをビルド対象コンテナイメージと同じレジストリ内にプッシュする、というパターンが挙げられます。ビルド対象コンテナイメージは、全シークレットへの参照を備えていることもあり、理想的にはランタイムからのみ呼び出されるべきです。しかし、アプリケーションのビルドに使用されるイメージは、ビルド対象コンテナイメージと同じレジストリ内に存在しているため、そこからシークレットにアクセスすることが可能です。結果、当該のイメージリポジトリにアクセスできる者ならば、誰でもこうした機密情報にアクセスできるようになります。今回の調査では、アプリケーションイメージの内部ではシークレットの参照が安全に行われているにもかかわらず、そのビルド用イメージにシークレットが含まれているケースも確認されました。
今回調査したオープンレジストリからは、CI/CDパイプラインに使用されるコンテナが数多く発見されました。これには、対象アプリケーション、ビルド、デプロイの各工程が含まれます。当該工程では、コンテンツ管理システムソフトウェアを介したソースコードのプル、リポジトリ用APIトークンの使用、クラウドサービスやログシステムへのアクセスに際し、各種シークレットが必要となります。今回はこうしたシークレットが、ファイルシステムやDockerfileの「.env」ディレクティブ内にハードコーディングされていました。言い換えると、シークレットがコンテナイメージのメタデータ内、あるいはファイル内に格納されていることになります。これらのイメージやファイルが置かれたコンテナレジストリにセキュリティ不備がある場合、重大な情報流出のリスクが発生すると考えられます。
CI/CDパイプラインの中でコンテナを使用する場合は、本調査から示される通り、シークレットの管理法に注意する必要があります。特にコンテナイメージにセキュリティ不備があると、攻撃者によって容易にアプリケーションの内部構成を解析され、外部攻撃の経路として利用される可能性があります。実際に、イメージレジストリのセキュリティ不備を突いた攻撃事例が、数多く確認されています。
一方、公開状態のコンテナレジストリに設定不備があると、複数のコンテナイメージが不正アクセスのリスクに晒されます。攻撃者によって当該イメージが徹底的に解析され、アプリケーションの構造や依存関係、設定、さらにはソースコードまで特定される可能性があります。こうした点からも、セキュリティ対策においては、設定不備の発見が重要な鍵となります。設定不備を見過ごし、これが不正利用された場合、特にクラウド環境のユーザは多大な損害を被る可能性があります。
従来型のサーバからコンテナへの変遷は、セキュリティ分野の様相を一変させました。コンテナはさまざまな恩恵をもたらしますが、広範に渡って利用されている現状を踏まえると、セキュリティ改善に向けた新たな取り組みが必要と考えられます。その効果を発揮するためには、警戒体制を維持することが重要です。
各サーバのセキュリティを個別で強化する従来型の方式は、コンテナをベースとする構成には適用できません。しかし、個々のコンテナを、独自の防御手段を備えた1つのアプリケーションと見立てることで、セキュリティを改善することは可能です。具体的にはイメージの暗号化、アクセス制御リスト(ACL:Access Control List)の作成、ファイアウォールの設置、VPN(Virtual Private Network)によるアクセスコントロールの実施などが考えられます。コンテナの利用を予定しているDevOpsの担当者は、セキュリティに細心の注意を払うと同時に、より安全な代替ソリューションについても検討、調査することを推奨します。
まとめ
本調査で述べたセキュリティ上の懸念点は、オープンコンテナレジストリから浮上したものです。入念な分析の結果、得に開発工程での注意を要するセキュリティリスクが明らかになりました。これを打開する上では、下記の対策が有効です。
- コンテナイメージのファイル内にシークレットをハードコーディングしない。
- シークレットやその参照については、専用のツールで保管、管理する。
- シークレットを環境変数として用意したい場合、それをDockerfileや.envなどのファイルに格納するのではなく、代わりに、コンテナのランタイム中にインジェクト(埋め込む)する。
- 私有のコンテナレジストリが外部公開されていないかどうか、確認する。
- コンテナイメージを暗号化する。
安全を確保するため、コンテナイメージレジストリの設定不備を定期的にチェックし、さらに、脆弱性やマルウェア、シークレットを常時スキャンすることを推奨します。安全かつ低容量でアプリケーションを稼働させたい場合は、Distrolessの利用を推奨します。シークレットについては、シークレットマネージャを用いてランタイム内に埋め込む方式が有効です。
開発者やセキュリティ担当の方は、本稿で挙げた課題を理解して主体的に対策を行うことで、不用意にアプリケーションをリスクに晒すことなく、コンテナの威力を十分に活動できると考えられます。
参考記事:
Mining Through Mountains of Information and Risk: Containers and Exposed Container Registries
By: Alfredo de Oliveira and David Fiser
翻訳:清水 浩平(Core Technology Marketing, Trend Micro™ Research)