Kubernetes Secret

ID

kubernetes_secret

Severity

high

Vendor

Kubernetes

Family

Generic Secret

Description

A Kubernetes Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Such information might otherwise be put in a Pod specification or in a container image. Using a Secret means that you don’t need to include confidential data in your application code.

Because Secrets can be created independently of the Pods that use them, there is less risk of the Secret (and its data) being exposed during the workflow of creating, viewing, and editing Pods. Kubernetes, and applications that run in your cluster, can also take additional precautions with Secrets, such as avoiding writing sensitive data to nonvolatile storage.

Secrets are then distributed into Pods using file paths in a volume, or exposed as environment variables.

There are eight different secret types that can be configured as Kubernetes resources.

Security

Any hardcoded Kubernetes secret is a potential secret reported by this detector.

Secrets are typically defined in a Kubernetes descriptor, and referenced by pods. Kubernetes secrets are, by default, stored unencrypted in the API server’s underlying datastore (etcd). Users can create a YAML file for Secrets using kubectl, or they can manually craft a file and upload it to the cluster.

Examples

apiVersion: v1
kind: Secret
#
type: Opaque

data:
  oracle_user: c3lzdGVtCg==
  # Clear-text password here (base64-encoded)
  oracle_pass: SGFja21lIQo=

metadata:
  ...

Using other tools like Kustomize does not matter if the descriptor is leaked:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

generators:
- secret.yaml

secretGenerator:
- name: my-secret
  literals:
  - username=admin
  - password=secret

In the following example, the SSL private key is only base64-encoded. As the private key is typically ready for deployment, it is not encrypted:

apiVersion: v1
kind: Secret
# TLS private key and certificate
type: kubernetes.io/tls

data:
  tls.crt: LS0tLS...EUtLS0tLQo=
  # This is the private key, leaked with this YAML descriptor
  tls.key: LS0tLS...tLS0tCg==

metadata:
  ...

Secrets can also be created dynamically using kubectl, but if this script is leaked, the secrets are also exposed:

kubectl create secret generic db-user-pass \
    --from-literal=oracle_user=system \
    --from-literal=oracle_pass='Hackme!'

Mitigation / Fix

  1. Renew or revoke the leaked secrets. Follow your policy for handling leaked secrets, which typically require revoking the secret in the target system(s). For example, if the leaked secret is an Opaque password for a database, follow the instructions for password renewal in the target database system.

  2. Remove the leaked descriptor. Remove the YAML descriptor file with secrets from the source code or committed configuration file.

  3. Check for potential misuse of the credentials. Check access logs in the target systems to ensure that the secret was not used by unintended actors during the compromised period.

  4. Prevent further leaks. Never leak configuration files containing secrets. Instead of hardcoding the secrets in kind: secret, either implement an specific mechanism that reloads configuration at runtime, or deploy a sidecar container that monitors for changes and restarts the main container when necessary.

    For example, the secret can be hosted in an external secrets vault, so the external secrets k8s operator will fetch the secret data from the vault and create a native Kubernetes secret with the same name. The generated secret can be used the same as with a regular hardcoded Secret resource. Example:

    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: db-external-secret
    spec:
      refreshInterval: 0.03m
      backendType: vault
      data:
        - secretKey: oracle_user
          remoteRef:
            key: secret/data/oracle/db01
            property: username
        - secretKey: oracle_pass
          remoteRef:
            key: secret/data/oracle/db01
            property: password

You should consider any sensitive data in commits with secrets as compromised.

Remember that secrets may be removed from history in your projects, but not in other users' cloned or forked repositories.

Reference