CVE-2023-40029 - Sensitive Cluster Secrets Exposed in Argo CD – Full Analysis, Exploit Detail & Remediation

---

*Argo CD is a popular tool for Kubernetes continuous deployment, relied on by thousands of teams for its declarative setup. But a design flaw disclosed as CVE-2023-40029 exposed a path where sensitive cluster secrets could leak to users with certain API privileges. This post walks you through what happened, how it can be exploited, and how to protect yourself—with simple explanations and hands-on code snippets.*

What is Argo CD and Why Cluster Secrets Matter

Argo CD manages Kubernetes deployments using a GitOps approach—meaning you describe your deployments in YAML, store them in Git, and let Argo CD sync them to your clusters.

To connect Argo CD to multiple Kubernetes clusters, you add cluster secrets—YAML documents usually containing endpoints, authentication tokens, or certificates. Sometimes these just identify the cluster; in other cases, they contain bearer tokens or authentication data.

Root Cause: Leaky Kubernetes Secret Annotations

Normally, secrets in Kubernetes are kept secure. But teams often manage these cluster secrets declaratively (with kubectl apply or via Argo CD manifests). When you use kubectl apply (client-side apply), Kubernetes adds an annotation called kubectl.kubernetes.io/last-applied-configuration. This stores the entire secret (including sensitive fields like tokens) in plain text in an annotation on the secret.

A code change (pull request #7139) added support for managing cluster labels and annotations via the Argo CD API. This also meant anyone with Argo CD API get permissions for clusters could see *all cluster annotations*—including the last-applied-configuration annotation containing your full secret.

Key permission to exploit:

- Needs clusters, get RBAC permission.

Here's what a typical affected cluster secret might look like

apiVersion: v1
kind: Secret
metadata:
  name: my-cluster
  labels:
    argocd.argoproj.io/secret-type: cluster
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {
        "apiVersion": "v1",
        "kind": "Secret",
        "metadata": {
          "name": "my-cluster",
          "labels": {
            "argocd.argoproj.io/secret-type": "cluster"
          }
        },
        "data": {
          "name": "my-cluster",
          "server": "https://prod.example.com:6443";,
          "config": "eyJiZWFyZXJUb2tlbiI6ICJzdXBlclNFQ1JFVCJ9"  # base64-encoded JSON: {"bearerToken": "superSECRET"}
        }
      }
type: Opaque
data:
  name: bXktY2x1c3Rlcg== # "my-cluster"
  server: aHRcHM6Ly9wcm9kLmV4YW1wbGUuY29tOjYNDM= # "https://prod.example.com:6443";
  config: eyJiZWFyZXJUb2tlbiI6ICJzdXBlclNFQ1JFVCJ9 # {"bearerToken": "superSECRET"}

Notice how the entire YAML (including the config, which has the bearer token) appears as a plain text annotation.

How an Attacker Could Exploit

1. Get RBAC Access: The attacker must have permission to list or get cluster resources via the Argo CD API (maybe a normal developer or system admin with clusters, get permission).
2. Read the Annotations: Using the Argo CD API, they can access the annotations. kubectl.kubernetes.io/last-applied-configuration gives them a full copy of the secret—sometimes including very sensitive bearer tokens!
3. Decode & Use: If bearer tokens are exposed, the attacker can authenticate directly to your Kubernetes cluster, possibly bypassing other audit controls.

Suppose Alice, a developer, has clusters, get access in Argo CD. She can run

# List all clusters via Argo CD CLI
argocd cluster list

# Get cluster info, dump all annotations including secrets!
argocd cluster get my-cluster -o yaml

Or via cURL and Argo CD API token

curl -H "Authorization: Bearer <ARGOCD_TOKEN>" \
  https://argocd.example.com/api/v1/clusters/my-cluster

Find the annotation

- Look for kubectl.kubernetes.io/last-applied-configuration

Copy, decode the base64 (if needed), and take the bearer token.

*In a worst-case scenario, Alice can now impersonate Argo CD and access the Kubernetes cluster with full admin rights.*

Argo CD 2.6.15+

See official advisory

If You Can't Upgrade

- Switch to Server-Side Apply: Create or update cluster secrets with kubectl apply --server-side. *Server-side apply does NOT create or rely on the last-applied-configuration annotation.*

Example

kubectl apply --server-side -f my-cluster-secret.yaml

- Remove annotation manually: For existing secrets, delete the dangerous annotation

kubectl annotate secret my-cluster \
  kubectl.kubernetes.io/last-applied-configuration-

References

- CVE-2023-40029 (NVD)
- Argo CD Security Advisory
- Original Pull Request (#7139)
- Complete Patch & Releases

Conclusion

This incident shows how small changes in how annotations are exposed can leak sensitive information—even when using best practices such as GitOps and declarative management. If you use Argo CD, check for this annotation in your cluster secrets. Always upgrade quickly, and minimize RBAC permissions where possible. Sometimes, secrets are more visible than you think.

Stay secure, check what you expose, and patch early!

*This post is exclusive and a result of independent research based on public disclosures. Always refer to upstream advisories for the latest guidance.*

Timeline

Published on: 09/07/2023 23:15:00 UTC
Last modified on: 09/13/2023 14:49:00 UTC