Argo CDで使われているRedisに脆弱性が発見されていました
Argo CDに脆弱性が発見されていましたので報告します。
対象バージョン
以下のバージョン未満のバージョンです。
- 2.11.1
- 2.10.10
- 2.9.15
- 2.8.19
逆に言うとこのバージョン以上ですと本脆弱性に対するパッチが適用済です。アップデートを検討ください。
Helmチャート
Helmチャートですと6.10.0にてパッチが適用されています。6.10.0未満のチャートをお使いの方はアップデートを検討ください。
どの部分に脆弱性があったのか
発見箇所はArgo CDで使われているRedisです。
Argo CDにおけるRedisの用途ですが、以下記載の通り単なるキャッシュです。
Redis is used by Argo CD to provide a cache layer reducing requests sent to the Kube API as well as to the Git provider. It also supports a few UI operations.
Component Architecture - Argo CD - Declarative GitOps CD for Kubernetes より引用
脆弱性詳細
このRedisはパスワード保護されていません。そのため攻撃者がこのRedisサーバーにアクセスできる場合、Redis のデータの読み取り/書き込みが可能です。 Redis内のデータを変更することで、Argo CDに任意のデプロイを実行させることが可能です。また任意の Kubernetes リソースの情報を取得する事もできます。詳細は以下をご確認ください。
「攻撃者がこのRedisサーバーにアクセスできる場合」と書きましたが、私の環境ではクラスター内の全namespace上のpodからアクセス可能な状態になっていました。
パッチ内容
端的に言うとRedisへのアクセスにパスワードが必要になりました = パスワード保護されるようになりました。
- パッチ適用前後のバージョンの比較: Comparing v2.11.0...v2.11.1 · argoproj/argo-cd
- Helmチャートのパッチ適用前後のバージョンの比較: Comparing argo-cd-6.9.3...argo-cd-6.10.0 · argoproj/argo-helm
解説(Helm)
私はHelmチャート経由でArgo CDをデプロイしていたのでHelmチャートについて解説します。
redis-secret-init job
まず、パッチが適用されたチャートバージョン6.10.0より、redis-secret-init
jobと、それに紐づくRole等が追加されました。
- argo-helm/charts/argo-cd/templates/redis-secret-init/job.yaml at argo-cd-6.10.0 · argoproj/argo-helm
これらredis-secret-init
関連のリソースのマニフェストファイルには以下のannotaionsが付与されています。
annotations: "helm.sh/hook": pre-install,pre-upgrade "helm.sh/hook-delete-policy": before-hook-creation
これらはChart Hooksのための設定です。
"helm.sh/hook": pre-install,pre-upgrade
によって、このHelmチャートリリースによる各種リソースの初回デプロイ前、もしくはアップグレード時にはアップグレード内容のデプロイ前にフックが実行されます。要は、他のリソースがデプロイされる前にこのjobが実行(作成)されるということですね。
"helm.sh/hook-delete-policy": before-hook-creation
に関しては、Hook deletion policiesというもので、新しいフックが起動される前に前回のフックで作成されたリソースを削除する、という指示です。
そしてこのジョブによって作成されるコンテナはargocdで、argocd admin redis-initial-password
コマンドを実行します。
# redis-secret-init jobのマニフェストファイルより抜粋 containers: - command: - argocd - admin - redis-initial-password image: quay.io/argoproj/argocd:v2.11.1
このコマンドの詳細は以下に記載されています。
要はRedisのパスワードを作成しているコマンドです。パスワードはargocd-redis
シークレットに格納されます。
Redis (Server)
上記フックのジョブで作成されたSecretを参照して環境変数を定義し、requirepass
オプションでその環境変数値を指定して、パスワード保護を有効化しています。
# redis deploymentのマニフェストファイルより抜粋 containers: - args: - --save - "" - --appendonly - "no" - --requirepass $(REDIS_PASSWORD) env: - name: REDIS_PASSWORD valueFrom: secretKeyRef: key: auth name: argocd-redis image: public.ecr.aws/docker/library/redis:7.2.4-alpine
RedisにアクセスするPod達
Redisにアクセスする必要があるPod達、具体的には Application Controller, Argo CD Server, Repo Serverでも前述のargocd-redis
シークレット値を参照して環境変数を定義し、Redisへの接続時に使用します。
# Application Controller StatefulSet のマニフェストファイルより抜粋 - name: REDIS_PASSWORD valueFrom: secretKeyRef: key: auth name: argocd-redis