Skip to content
Sedat Özdemir
Writing

devsecops

Is Everyone Root in Your K8s Cluster? Let's Stop the Orchestration Chaos

A deep dive into common Kubernetes security pitfalls like wide-open API servers and over-privileged RBAC roles, and how to secure them from a Red Teamer's perspective.

Sedat Özdemir
· 4 dk read

Have you ever woken up to a cold sweat after seeing a 'Why was the entire namespace deleted?' message on Slack while everything seemed to be running smoothly in production? If the answer is 'no,' you're either very lucky or no one has poked at those famous Kubernetes (K8s) 'default' settings yet. But as you know, Red Teamers and attackers absolutely love those defaults.

Kubernetes is the conductor of the modern software world. However, this conductor can sometimes be so generous that it gives every instrument (or pod) on stage the authority to manage the entire orchestra. Today, let's talk about the K8s security vulnerabilities we frequently encounter at our testCompany labs—the ones often dismissed as 'it works, don't touch it'—which are actually ticking time bombs, and how we can patch them.

API Server: Your Ticket into the Castle

The kube-apiserver is the heart of the K8s world. Everything flows through it. If you leave this door open, a simple curl command is all an attacker needs to get inside. We often see anonymous access allowed in development environments just for 'convenience.' This is like putting the shop keys under the doormat and hanging a neon sign that says 'Keys Are Here.'

What should you do? First, make sure the anonymous-auth parameter is set to false. Additionally, the most logical move is to whitelist the API Server to specific IP blocks or hide it from the external world entirely.

RBAC: Who, Where, and What? (Or What They Can't Do)

Role-Based Access Control (RBAC) is the backbone of K8s security. Yet, to avoid 'Permission Denied' errors, everyone often ends up being granted cluster-admin privileges. It’s a total disaster scenario when a pod that only needs to read a configmap in its own namespace has the authority to list secrets across the entire cluster.

From a Red Teamer's perspective, the first thing I look for to exploit an entire cluster through a single compromised pod is an 'Over-privileged ServiceAccount.'

Defanged Example: A Dangerous ClusterRole

# THIS IS A SECURITY RISK - DO NOT USE
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: over-privileged-role
rules:
- apiGroups: [""]
  resources: ["*"] # Access to every resource
  verbs: ["*"]    # Ability to perform any action

When you bind this kind of role to a pod (via a ServiceAccount), an attacker inside that pod can pull all your secrets with the following command: curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://127.0.0.1:6443/api/v1/secrets

The Solution: Principle of Least Privilege. Give only what is needed, and only for as long as it's needed.

Containers Aren't Limitless: Privileged Pods

Don't say 'I'm running inside Docker, nothing can happen to me.' If a pod is running with the privileged: true flag, that pod essentially holds almost all the privileges of the host machine. An attacker can access the host's file system through this pod (via mounts) and potentially escape the container entirely.

Related posts