Compromised Container Blast Radius
Assume the application is already owned - a dependency, an upload handler, an unauthenticated admin path - and ask what the attacker now has. On a default cluster the answer is root, a bounded capability set, and a credential nobody chose to give them.
Kubernetes Threat Model Guide 28 of 42 Intermediate
- Kubernetesapiserver v1.36.4, kubelet v1.36.3
- Runtimecontainerd 2.2.6
- CNICilium 1.18.1
- Built withkubeadm v1.36.3
- TimeAbout 18 min
CapEff is read from /proc/1/status and reflects containerd's default capability set, which does not include CAP_SYS_ADMIN. Containers run as root unless the image or the Pod spec says otherwise.
- Host kernel7.0.0-29
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| CKA5001 | 192.168.0.41 | Ubuntu 26.04 LTS | Control Plane Node (tainted NoSchedule) | 2 Core | 4 GB | 50 GB |
| CKA5001-NODE01 | 192.168.0.42 | Ubuntu 26.04 LTS | Worker Node | 2 Core | 4 GB | 50 GB |
| CKA5001-NODE02 | 192.168.0.43 | Ubuntu 26.04 LTS | Worker Node | 2 Core | 4 GB | 50 GB |
| CKA5001-NODE03 | 192.168.0.44 | Ubuntu 26.04 LTS | Worker Node | 2 Core | 4 GB | 50 GB |
This guide includes
Use this when the assumption is that the application is already owned. This matters because the interesting question is not how they got in - it is what the container was handed, and a mounted token is a credential nobody asked for.
- starting from root in the container, holding a credential you never requested
- trying a privileged operation and reading the capability set that refused it
- asking the API what that token is genuinely permitted to do
- using it to reach a neighbour, from inside the compromised container
- seeing the single field that removes the credential altogether
Before you start
-
The starting position: root, and a credential you did not ask for
-
Root in the container is not root on the node
-
What the token is allowed to do
-
Using it, and reaching the neighbour
-
The mitigation you can see