Skip to content
Sedat Özdemir
Writing

container-security

Kubernetes: Orchestration Magic or a Trojan Horse Within?

Is your K8s cluster a secure fortress or just a playground for attackers? Let's dive into API server security, RBAC pitfalls, and why Base64 isn't encryption.

Sedat Özdemir
· 4 dk read

Ever woken up at the crack of dawn to a message like 'The cluster is blown, pods are eating each other,' only to realize the issue was just port 6443 being wide open to the world? If you smirked or felt a slight shiver down your spine while reading that, you’re in the right place.

Hey folks, Sedat here. Today, we’re diving into the world of Kubernetes (K8s)—the crown jewel of modern infrastructure and occasionally a security pro's nightmare. On the Red Team side, our eyes light up when we see a K8s cluster because we usually find a massive playground built with the 'just make it work' mentality. But today, I’m switching sides to talk about how we can turn that playground into a fortified stronghold.

API Server: Leaving the Heart's Gates Open

The API Server is the brain of Kubernetes. Everything flows through it. If you don't protect it properly, you’re essentially handing over the keys to the entire kingdom on a silver platter.

One of the most classic mistakes we see during penetration tests at testCompany is leaving the --anonymous-auth=true flag active. It’s like telling security at the gate, 'I don't care who I am, just let me in.'

As an attacker, I could do this:

# Defanged K8s API request
curl -k https://127.0.0.1:6443/api/v1/namespaces/default/pods

If this command returns an output, it's game over. It means I can see all the pods and their environment variables—where database passwords usually live.

What should we do? Disable anonymous access in your API Server configuration and always use RBAC (Role-Based Access Control). Also, never expose the API Server to the internet; keep it restricted to the internal network or specific VPN IPs. Whitelisting saves lives.

RBAC: Time to Exit 'Everyone is Admin' Mode

A huge misconception in the K8s world is giving developers or ServiceAccounts more permissions than they actually need. If a microservice only needs to list pods in its own namespace, don't give it cluster-admin rights. That’s like using an atomic bomb to kill a fly.

During Red Team operations, the first thing we do when we compromise a pod is check the /var/run/secrets/kubernetes.io/serviceaccount/token file. If we can run kubectl get secrets --all-namespaces with that token, the cluster is ours.

Take a look at this dangerous ClusterRole example:

# DANGEROUS - ClusterRole Example
apiversion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: the-do-it-all-role
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["*"] # Can do everything!

Instead, apply the principle of 'Least Privilege.' Only grant the necessary permissions for the specific resource required.

Secrets: Base64 is Not Encryption!

I say this every chance I get, but it still pops up: Base64 is not an encryption method; it’s just an encoding format. Kubernetes secrets are stored by default in etcd as Base64 strings. Anyone with access to etcd or the ability to read secrets can decode them instantly. Always use a proper secrets management solution like HashiCorp Vault or integrate with a Cloud KMS.

Related posts