Originally reported: October 2019 | CVE: CVE-2019-11253 | Discovered by: StackRox
Overview
In late 2019, security firm StackRox disclosed a potentially serious vulnerability in the Kubernetes API server, tracked as CVE-2019-11253. The vulnerability allowed an attacker to craft a malicious YAML payload that could trigger a billion laughs-style denial-of-service (DoS) attack against the Kubernetes API server (apiserver). At the time of the original disclosure, Kubernetes had not yet released a patch, and the full technical details were reserved pending an official public announcement from the Kubernetes security team.
What Is a Billion Laughs Attack?
The “billion laughs” attack is a well-known class of denial-of-service exploit originally associated with XML parsing. It works by defining a chain of nested entity references that expand exponentially when processed. A small, seemingly innocent input file can cause a parser to consume enormous amounts of memory and CPU as it recursively resolves each reference, effectively exhausting system resources and making the service unavailable.
While the attack is most historically associated with XML (where it is sometimes called an XML Entity Expansion attack), the same underlying principle can apply to any data format or parser that supports self-referential or recursive constructs — including YAML.
How the Vulnerability Affected Kubernetes
The Kubernetes API server is the central control-plane component that accepts and processes all API requests for a cluster. Among the payload formats it accepts are YAML manifests — the standard way Kubernetes users define resources such as Deployments, Services, and ConfigMaps.
YAML supports anchors and aliases, a feature that allows a value defined in one part of a document to be referenced (aliased) in other parts. When these aliases are nested — that is, when an alias refers to a node that itself contains aliases — and the parser expands all references without restriction, the memory footprint can grow exponentially.
According to StackRox’s disclosure, the Kubernetes apiserver had two key weaknesses that made this exploitable:
- No input validation on uploaded YAML: The API server did not inspect or reject malformed or maliciously crafted YAML payloads before processing them.
- No hard limit on expanded document size: There was no cap on how large the in-memory representation of an uploaded YAML document could grow after all aliases and references were resolved.
Together, these gaps meant that any entity with the ability to submit a YAML payload to the API server could potentially exhaust the server’s memory and bring down the control plane.
Who Could Exploit It?
The severity of the vulnerability depended heavily on what access an attacker already had. An unauthenticated attacker could exploit it only if the API server allowed anonymous requests (which is disabled by default in many configurations but can be inadvertently left enabled). An authenticated user — including one with limited RBAC permissions — who could submit resource manifests would also have a potential attack vector.
This is why StackRox emphasized that access to the Kubernetes API server itself must be treated as a sensitive privilege, independent of what application-level RBAC policies are in place. As StackRox stated at the time:
“The issue once again serves as a reminder that, like all software, Kubernetes is vulnerable to zero-day exploits. Thus, mere access to your Kubernetes API server should be treated as sensitive, regardless of how tight your application-level authorization policies (i.e., Kubernetes RBAC) are.”
StackRox
Recommended Mitigations
While awaiting an official patch, StackRox recommended the following defensive measures to reduce exposure:
1. Audit and Tighten RBAC Policies
Review your Kubernetes Role-Based Access Control (RBAC) configuration to ensure that only trusted, identified entities have the ability to create or update resources in the cluster. Least-privilege principles apply: no user or service account should have broader permissions than strictly required.
2. Regularly Audit Cluster Roles and Bindings
Perform routine audits of ClusterRole, Role, ClusterRoleBinding, and RoleBinding objects. Identify any bindings that grant resource-creation permissions to low-trust or external entities and remove or restrict them.
3. Disable Anonymous Authentication
Pass the --anonymous-auth=false flag to both the API server and Kubelets to ensure that unauthenticated requests are rejected outright. This removes one of the easiest paths for an external attacker to reach the vulnerable parser. Be aware that even leaking information such as the API server version or the fact that a Kubernetes API server is running on a given host can be useful intelligence for an attacker.
4. Do Not Expose the API Server to the Public Internet
The Kubernetes API server endpoint should never be directly reachable from the public internet. Place it behind network firewalls, and restrict access to trusted private subnets or Virtual Private Cloud (VPC) networks. Use bastion hosts, VPNs, or other access-control mechanisms for operators who need remote access.
The Broader Lesson: Defense in Depth for Kubernetes
CVE-2019-11253 illustrates a recurring principle in Kubernetes security: the API server is the most sensitive component in a cluster, and any access to it — even with apparently limited permissions — must be considered a potential attack surface. Relying solely on RBAC without also hardening network access, disabling unnecessary features, and monitoring API server behavior leaves clusters exposed to vulnerabilities that bypass application-layer controls entirely.
Organizations running Kubernetes in production should treat API server hardening as a continuous practice, not a one-time configuration step. Regularly review the Kubernetes documentation on securing a cluster and monitor CVE disclosures through the Kubernetes security advisory process.
Note: CVE-2019-11253 was disclosed in 2019. If you are running a Kubernetes version released after that date, verify whether your version includes the upstream fix by checking the official Kubernetes changelog and your distribution’s release notes.