Skip to content
Sedat Özdemir
Writing

container-security

Getting Lost in YAML: The High Cost of Leaving Kubernetes Security to 'Default' Settings

Think your K8s cluster is secure because it's 'running'? Think again. From RBAC nightmares to privileged pod escapes, let's look at why default settings are a Red Teamer's best friend.

Sedat Özdemir
· 4 dk read

Remember the taste of that bitter coffee you had to drink when you realized the intern you gave cluster-admin access to 'accidentally' deleted the entire production environment with a single kubectl command? If you haven't tasted that coffee yet, you're either very lucky or you've fallen into the false sense of security created by 'default' settings in the Kubernetes (K8s) world.

Hey everyone, I'm Sedat. Today, we're diving into the dark alleys of the orchestration world—K8s security. On the Red Team side, our job isn't just to break in; it's to explain exactly why those doors were left wide open. When it comes to K8s, the common mentality is often 'It’s up and running, let’s move on.' But that 'working' system might actually be providing a massive playground for an attacker. Let’s look at how we can tame this beast based on our simulations at testCompany and our experience in the field.

RBAC: The End of the 'Everyone is Admin' Mentality

The first mistake usually made after a K8s installation is handing out the cluster-admin role like candy. Why? Because no one wants to deal with 'Forbidden' errors while trying to do their job. But here's what we forget: RBAC (Role-Based Access Control) isn't just for humans; it applies to ServiceAccounts too. Imagine an attacker breaches a pod. If the ServiceAccount used by that pod has unnecessarily broad permissions, the attacker doesn't just move laterally; they move vertically straight to the top.

Check this out—this YAML file is basically a 'recipe for disaster':

# THIS IS A BAD EXAMPLE - Do not let this near production!
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: default-sa-admin-binding
subjects:
- kind: ServiceAccount
  name: default
  namespace: dev-team
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

What’s happening here? We’ve given 'God-mode' permissions to the 'default' service account in the dev-team namespace across the entire cluster. If an attacker hacks a simple web app running in this namespace, they now hold the keys to the kingdom.

The Fix? The Principle of Least Privilege. A pod should only have access to the specific APIs it needs. Better yet, if a pod doesn't need to talk to the API server at all, set automountServiceAccountToken: false. If it's not needed, why leave it there?

Container Escapes and Privileged Pods

Let’s look at something a bit more technical: privileged: true. This setting allows a container to have almost all the same capabilities as the host machine. In Red Team operations, if we see a pod with this setting enabled, we usually get to go home early because escaping to the host machine takes mere seconds.

Here’s a look at a 'dangerous' pod configuration:

apiVersion: v1
kind: Pod
metadata:
  name: dangerous-pod
spec:
  containers:
  - name: exploit-container
    image: example.com/security-tool:latest
    securityContext:
      privileged: true # This is where things go south.

When you run a pod like this, you're essentially breaking the isolation barrier that containerization is supposed to provide. An attacker inside this pod can access the host’s devices, mount the host’s file system, and eventually take over the entire node.

Always audit your security contexts and use tools like Kyverno or OPA (Open Policy Agent) to block these kinds of configurations from ever reaching your cluster.

Related posts