mediumCWE-312OWASP A02:2021

Kubernetes Secrets Not Encrypted at Rest

Kubernetes Secrets are stored as base64-encoded plaintext in etcd by default, meaning anyone with access to the etcd datastore or its backups can read every secret in the cluster.

How It Works

When you create a Kubernetes Secret, the data is base64-encoded (not encrypted) and stored in etcd, the cluster's key-value store. Base64 is an encoding, not encryption -- decoding it is trivial. If an attacker gains access to etcd (via a misconfigured endpoint, an etcd backup, or compromised node), they can read every database password, API key, and TLS certificate in the cluster. Kubernetes supports encryption at rest via an EncryptionConfiguration that encrypts Secret data before writing it to etcd, but this must be explicitly configured. Most self-managed clusters and even some managed clusters do not enable this by default.

Vulnerable Code
# BAD: Secret stored as base64 only -- not encrypted at rest
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=          # echo -n 'admin' | base64
  password: UEBzc3cwcmQxMjM=  # echo -n 'P@ssw0rd123' | base64
# Without EncryptionConfiguration, this is stored as-is in etcd
# Anyone with etcd access can decode: echo 'UEBzc3cwcmQxMjM=' | base64 -d
Secure Code
# GOOD: enable encryption at rest for Secrets in etcd
# /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources: ["secrets"]
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}  # fallback for reading unencrypted secrets
# Pass to kube-apiserver: --encryption-provider-config=/etc/kubernetes/encryption-config.yaml
# Then re-encrypt existing secrets: kubectl get secrets --all-namespaces -o json | kubectl replace -f -

Real-World Example

In 2022, security researchers at Palo Alto Networks (Unit 42) demonstrated that 75% of Kubernetes clusters scanned in the wild had etcd accessible without proper authentication, and none of the exposed clusters had encryption at rest enabled. Attackers could read all Secrets including cloud provider credentials, database passwords, and service account tokens directly from etcd.

How to Prevent It

  • Enable encryption at rest using EncryptionConfiguration with AES-CBC or AES-GCM providers on the Kubernetes API server
  • Use a KMS provider plugin (AWS KMS, GCP Cloud KMS, Azure Key Vault) so encryption keys are managed externally and rotated automatically
  • Restrict etcd access to only the kube-apiserver -- never expose etcd endpoints to the network or other pods
  • Use external secrets management (HashiCorp Vault, external-secrets-operator) instead of native Kubernetes Secrets when possible

Affected Technologies

TerraformKubernetesDocker

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities