コンテナレジストリの「信頼の境界線」を突破せよ:イメージ改ざんという静かなる侵入
多くのテックリードは、CI/CDパイプラインを「堅牢な要塞」だと誤認している。しかし、現場のペネトレーションテストにおいて、コンテナレジストリ(ECR, GCR, Harbor等)は、もっとも脆弱な「信頼の盲点」になり得ることが多い。
今日は、単なる「認証の不備」という表層的な話ではない。攻撃者がどのようにレジストリのプロトコル仕様を悪用し、イメージ署名をバイパスして、デプロイメントの心臓部を汚染するのか。その深淵に潜む防衛アーキテクチャを解き明かす。
—
1. プロトコル層の欠陥:レジストリAPIの罠
コンテナレジストリの通信プロトコル(Docker Registry HTTP API V2)は、非常にシンプルだが、そのシンプルさゆえに「認可の粒度」が甘くなる傾向がある。
攻撃者は、しばしばmanifestの操作を狙う。多くの環境では、push権限を持つサービスアカウントが「イメージの削除」や「タグの付け替え(Image Tag Mutability)」まで許可されている。これが致命傷だ。
もしレジストリ設定で Image Tag Mutability が無効化されている場合、攻撃者はCI/CDがビルドした正規のイメージを、同名の悪意あるイメージで上書きできる。ハッシュ値(Digest)の検証を怠っているパイプラインであれば、実行環境は「見た目は同じだが、中身はバックドアだらけ」のコンテナを平然とプルする。
防御の要点:Immutable Tagの強制
まずは設定レベルで防ぐ。これが基本中の基本だ。
# Harbor等であればプロジェクト設定で「タグの不変性(Tag Immutability)」を有効化する
# AWS ECRであれば、リポジトリポリシーで DeleteImage 権限を極限まで絞る
# 以下のポリシーは、CI用アカウント以外に上書きを許さない例
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RestrictTagOverwriting",
"Effect": "Deny",
"Principal": "*",
"Action": [
"ecr:PutImage",
"ecr:BatchDeleteImage"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": "arn:aws:iam::123456789012:role/ci-pipeline-role"
}
}
}
]
}
—
2. Cosignによる「真の信頼」の構築
タグの不変性を担保したとしても、レジストリ自体が侵害されたら終わりだ。そこで登場するのが、Sigstoreの Cosign を用いた「イメージ署名」である。
多くのエンジニアは署名を「単なるチェックサム」と勘違いしているが、これは暗号学的なアイデンティティ証明だ。重要なのは、デプロイ時に署名を検証するだけでなく、「誰が署名したか」を厳格に管理することである。
Cosignを使った署名の実装例
CIパイプラインの最後で、イメージにデジタル署名を付与する。
# 秘密鍵で署名を行い、署名をレジストリにプッシュ
cosign sign --key cosign.key my-registry.com/my-app:v1.0.0
# デプロイメントコントローラ(KyvernoやAdmission Controller)側で検証を強制するポリシーの概念
# 署名なしのイメージは、Kubernetesクラスターに入れない
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: check-signature
match:
resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "my-registry.com/my-app:*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
... (公開鍵) ...
-----END PUBLIC KEY-----
—
3. 生成AI時代の新たな脅威:プロンプトインジェクションとイメージの因果関係
最近のレッドチーム活動では、LLMを活用した自動ビルドエージェントを狙う事例が増えている。例えば、開発者がLLMに「Dockerfileを最適化して」と頼んだ際、悪意ある RUN コマンドが挿入されるケースだ。
さらに恐ろしいのは、レジストリに格納されたイメージの中に「LLMが学習データとして読み込む可能性のあるライブラリ」が含まれている場合、そのライブラリ自体に細工を施すことで、下流のAIモデルを汚染する(AI Supply Chain Attack)というシナリオが現実味を帯びている。
防御のアーキテクチャ:ガードレイルの設計
- 静的解析の自動化:
TrivyやGrypeを使い、ビルド直後にOSライブラリだけでなく、アプリケーション依存関係の脆弱性をスキャンする。 - SBOM (Software Bill of Materials) の生成:
Syft等を用いてSBOMを生成し、レジストリに署名付きで保存する。これにより、「何が入っているか」を事後的に追跡可能にする。 - 耐量子暗号への備え: 将来的な量子コンピュータによるRSA/ECDSAの破綻を見据え、署名方式に耐量子署名(LMSやXMSS)の検討を開始する時期に来ている。
—
結論:セキュリティは「性悪説」の上に構築する
コンテナレジストリは、単なるストレージではない。それは「コードという名の爆弾」を保管する兵器庫だ。
1. レジストリのAPIアクセスを最小特権にせよ(特に削除・上書き権限)。
2. Cosignによる署名を必須とし、未署名イメージの実行を拒絶せよ。
3. SBOMを通じた可視化を徹底し、サプライチェーンの透明性を担保せよ。
「自分たちが管理しているから大丈夫」という慢心こそが、攻撃者にとっての最大の好機であることを忘れないでほしい。真のホワイトハッカーは、自らのアーキテクチャを常に「既に侵害されている」という前提で設計し、その中でいかに攻撃の連鎖を断ち切るかを考えている。
次は、レジストリのメモリ管理の不備を突くエクスプロイト手法について深掘りする。準備はいいか?
コメント