As we saw in our recent post, the goal of a Kubernetes threat model is to offer a comprehensive view of potential threats and corresponding mitigations, serving as a practical checklist to identify common attack vectors. It helps uncover how attackers might exploit misconfigurations or weaknesses in the cluster to achieve their objectives.
In 2020, the Cloud Native Computing Foundation (CNCF) Financial User Group conducted an in-depth threat modeling exercise on Kubernetes clusters. This initiative aimed to provide a comprehensive view of potential threats and their mitigations within Kubernetes environments. A central outcome of this effort was the development of attack trees, which systematically outline how adversaries might exploit vulnerabilities to compromise a cluster.
What is an Attack Tree?
An attack tree is a structured, hierarchical diagram used to model the different ways an attacker could compromise a system. At the top of the tree is the attacker’s main objective (the "root"), such as gaining control over a Kubernetes cluster or accessing sensitive data. Branching out from this root are various paths the attacker could take, broken down into smaller, more specific steps or conditions that must be met to achieve that goal. Each node in the tree represents an action or event, and branches can represent either AND or OR conditions, depending on whether all or just one of the child actions is required for progress toward the goal.In the context of threat modeling for Kubernetes, attack trees help security teams visualize and prioritize potential attack paths across different layers of the cluster — from the control plane to workloads and network configurations. By building an attack tree, we can identify where an attacker might gain an initial foothold (e.g., a misconfigured pod), how they could escalate privileges (e.g., exploiting over-permissive RBAC), and what they could ultimately achieve (e.g., data exfiltration). These trees are very useful for mapping defenses to specific threats, validating security controls, and ensuring teams are prepared to mitigate real-world attack scenarios.
Types of Attack Trees
The attack trees created in this exercise follow two approaches:Bottom-Up Approach
The bottom-up approach starts by identifying technical vulnerabilities or entry points in the system and then works upwards to understand how those could lead to more serious outcomes (like data breaches or full cluster compromise).This is how it works:
- We start by identifying low-level threats: misconfigurations, exposed ports, weak RBAC roles, insecure container images, etc.
- For each threat, we ask the question: “What could an attacker do next if they exploited this vulnerability?”
- Then, we continue mapping out each step the attacker might take to escalate privileges or move laterally.
- Eventually, we would reach a high-level attacker goal (e.g., "Gain control over the cluster").
First we will identify our entry point, a vulnerability that we could exploit in our K8s environment. Let’s say we’ve identified a pod running with:
runAsUser: 0
(i.e., running as root),hostPath
volume mount to the node filesystem,- No AppArmor or Seccomp profile.
- Since
runAsUser: 0
, they’re running as root inside the container. - This gives them elevated privileges inside the container namespace
- The hostPath volume mount exposes the entire or part the host filesystem. With that access, and using the root user the attacker can then view and edit files like /etc/passwd or /etc/shadow which contain users and passwords in the host.
- That means the attacker can then modify binaries, systemd units, or SSH configuration which will allow them to inject scripts or backdoors into startup locations. That will make the attacker be able to escape the container and access take control of the node. From this point on, the attacker can bring down our worker node
Following this approach we can build a technical control map by identifying the various entry points to our K8s platform and then we can validate our defense-in-depth strategies, ensuring low-level vulnerabilities don’t lead to critical breaches.
Scenario-Based Approach
The scenario-based approach starts with a realistic attack goal or adversary profile, then maps downwards all the possible paths an attacker might take to achieve that objective.This is how it works:
- Start by defining a scenario: e.g., “An insider wants to exfiltrate customer data” or “An external attacker compromises a CI/CD pipeline.”
- For each scenario, we ask the question: “What steps would the attacker need to take?” and “What conditions would enable them to achieve that goal?”
- Then, we break down the attack into stages (initial access, privilege escalation, persistence, exfiltration).
- Build the tree from the top (goal) to the leaves (actions or conditions).
Example: Let’s now build our attack tree from the top-down.
We’ll start by defining our scenario: An external attacker wants to gain administrative access to a cluster
Now, What steps would the attacker need to take?
- First, if we want to take control of the cluster, we need to get access to the Kube API server and be able to send requests that would be accepted by the API server.
- For that, the attacker could use a malicious pod in a high-privilege namespace
- To do so, the attacker would need a valid token or password. So, the attacker could try steal a valid token or break a weak password
- Where can an attacker find those? one way to do that would be by accessing mounted secrets in a compromised pod
- The attacker could also get those by accessing a configMap or variables containing sensitive information in the pod
- Lastly, another possibility is that the attacker finds these credentials in the logs of one of our apps and pods
That is our attack tree. In this case we’ve started by the attacker goal and built the path that an attacker could follow to achieve it. And with that we’ve found some of the mechanisms we need to put in place to block that path, such as, protecting our secrets or logs.
Both approaches are valuable and often used together. We could use the bottom-up model to assess our current Kubernetes security posture, and the scenario-based approach to test how well it holds up against specific attack narratives.
The set of attack trees created by the CNCF Financial User Group are open source and are available in this GitHub project. Here’s a quick summary of them:
The set of attack trees created by the CNCF Financial User Group are open source and are available in this GitHub project. Here’s a quick summary of them:
Key Attack Trees
The CNCF Financial User Group describes 6 Attack Trees in this exercise:Malicious Code Execution
In this attack tree, we explain the different steps an attacker could take to run malicious code in our K8s cluster. It is a bottom-up attack tree, so the attack tree is built by starting with an existing vulnerability. In this attack tree it uses two entrypoints for the attack:- A compromised app that provides access to the container. Exploiting that vulnerability the attacker will be able to get access to the container and then importing its malicious code into the container.
- The image pull secret compromised. If that happens then the attacker can then poison the image repository either by modifying and updating existing images or by injecting the malicious code in a poisoned image that would be pushed to our repository.
Establish Persistence
This attack tree explores how an attacker can maintain long-term access within the cluster (persistence). This is a bottom-up attack tree, so the attack tree represents different paths that an attacker could follow starting by exploiting some vulnerable areas in our environment. There are two main branches in this attack tree - One branch starts by accessing secrets within the cluster to exploit other vulnerable components, while another branch highlights scenarios where an attacker gains access to a container and uses misconfigurations to establish persistence that survives container, pod, or node restarts.Access Sensitive Data
This follows a bottom-up approach with the goal of retrieving confidential information from our K8s cluster. The attack tree describes the different approaches an attacker could take by exploiting the following vulnerabilities:- Misconfigured RBAC permissions
- Sensitive information in logs
- Eavesdropping on network traffic
- Access to read ConfigMaps or secrets
- Access to read Persistent Volumes
Denial of Service
This attack tree follows a bottom up approach. The attack tree in this case describes the two main approaches that an attacker could take to launch a DoS attack to our K8s cluster- An attacker could exhaust cluster resources by compromising a container and initiating resource-intensive processes.
- Alternatively, with network access to the control plane, they might flood endpoints to exhaust resources.
Compromised Container
This is one of the two scenario-based attack trees provided in this exercise. In this first scenario, the attack tree shows the different paths that an attacker could take once they can exploit a compromised application running in a container and the consequences (scenarios) of that
Attacker on the Network
The second scenario-based attack tree examines the different paths an attacker could take if they got access to the internal network hosting our K8s cluster. When this happens, Attackers can target Kubernetes control plane and nodes and launch DoS attacks to disrupt or take down our server in different ways:- Exhausting compute resources - This can be done by modifying configuration files in the host or by bringing down the kubelets (targetting the kubelet ports
- Disrupting workloads - Targetting the different ports used by the K8s components (api server, controller manager, etcd, scheduler)
- Disrupting the Cluster Networking - Messing up the internal and external communication in the K8s cluster.