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.
# 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# 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
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
Terraform State Exposed
criticalYour terraform.tfstate file is committed to your repository or stored in an unencrypted, publicly accessible location — it contains every secret and resource ID in your infrastructure.
Terraform Provider Credentials Hardcoded
criticalAWS, GCP, or Azure credentials are hardcoded in your .tf files instead of using environment variables or instance roles, committing cloud access keys to version control.
Kubernetes Privileged Container
highYour Kubernetes pod runs with securityContext.privileged: true, giving the container full access to the host kernel and effectively bypassing container isolation.
Kubernetes Default Service Account
mediumPods running with the default service account inherit cluster-level RBAC permissions that are often far more powerful than the workload needs, enabling lateral movement if the pod is compromised.