skip to main content

Jun 5, 2020

Mitigating CVE-2020-10749 in Kubernetes Environments

By: Viswajith Venugopal

A vulnerability that might enable a man-in-the-middle attack on Kubernetes clusters, CVE-2020-10749, was disclosed a few days ago. This vulnerability is not in Kubernetes itself but rather in certain container networking implementations — IPv4-only clusters using affected implementations are vulnerable.

The vulnerability allows for man-in-the-middle (MITM) attacks, where an attacker can intercept network traffic to a pod in a Kubernetes cluster and impersonate it to clients.

How It Works

To understand this vulnerability, here’s some relevant background:

  • Router advertisements: A component of the neighbor discovery protocol for IPv6 (specified in RFC 4861), router advertisements are a type of message broadcast by routers to advertise their presence — essentially, a router advertisement message informs recipients that there exists a IPv6 router, at the address specified in the message, which can route certain IPv6 traffic.
  • CAP_NET_RAW: CAP_NET_RAW is a powerful Linux capability that allows processes with it to forge any kind of packet or bind to any address. Importantly, containers with the CAP_NET_RAW capability can send out IPv6 router advertisements.
  • Client preference for IPv6 vs. IPv4: In an IPv4-only cluster, no containers are accessible through IPv6 addresses. However, if the DNS for the cluster returns both IPv4 (A) and IPv6 (AAAA) records, many clients will preferentially try the IPv6 address and fall back to the IPv4 address.

With this context, here’s how an exploit of CVE-2020-10749 works. Consider an IPv4-only cluster, where no IPv6 addresses have ever been routed before. If an attacker gains access to one of your pods, which has CAP_NET_RAW, they can send out “rogue” IPv6 router advertisements, which claim that the attacker’s pod is an IPv6 router that knows how to resolve all IPv6 addresses. Vulnerable container networking implementations will now send all traffic for which DNS returns an IPv6 record to the attacker’s pod, allowing it to see this traffic and successfully act as a man-in-the-middle, impersonating the server to the client and the client to the server.

How To Know If Your Cluster is Vulnerable

For a cluster to be vulnerable, the following conditions must be true:

  1. The cluster is an IPv4-only cluster.
  2. The cluster uses an affected container networking implementation. Kubelet versions 1.18.0-1.18.3, 1.17.0-1.17.6, and earlier than 1.16.11 are all affected, as are several third-party components and versions. See this post for the full list. If you use the StackRox Kubernetes Security Platform, you can check whether your clusters are running an affected version in the Vulnerability Management section. Kubernetes CVE screen shot
  3. The cluster is running pods that have the CAP_NET_RAW capability. This capability is part of the default set of Docker capabilities, so containers will run with this capability unless it is explicitly dropped in the pod or container SecurityContexts (by adding it to the SecurityContext.Capabilities.drop array).

Additionally, a specific deployment in the cluster is exposed to this vulnerability only if it accepts non-TLS connections or TLS connections that do not perform certificate validation — proper TLS usage will always thwart man-in-the-middle attacks from the networking layer. However, even if a deployment uses TLS properly, an attacker can still use the same techniques to perform a denial of service (DoS) attack.

How To Mitigate This Issue

At this time, a patched version of kubelet has not yet been released — the expected date is June 17. Users should upgrade their kubelet version as soon as the patch is released. Until then, you can mitigate against the threat posed by this vulnerability using the following steps:

  1. Configure hosts to reject router advertisements by default — this setup will thwart this attack, but it may break legitimate traffic. Breaking legitimate traffic, however, is unlikely on an IPv4-only cluster. To change this setting, set the kernel parameter net.ipv6.conf.all.accept_ra to 0 on your hosts (to make this setting persistent, you need to edit /etc/sysctl.conf).
  2. Disable CAP_NET_RAW on your pods by default, enabling it only for the pods that need it. You can enforce this policy (and carve out the exceptions you need) using policies in the StackRox Kubernetes Security Platform.
  3. Use TLS with certificate validation on your requests. As already noted, however, this step cannot prevent DoS attacks.
  4. Harden your cluster, and ensure you have the visibility you need to detect attacks. To exploit this vulnerability, an attacker must control one of the pods in your cluster, which can happen if you unwittingly install a malicious pod, or an attacker uses other means to gain control of one of your pods. Following Kubernetes security best practices can significantly mitigate the risk of this happening.

As with many vulnerabilities, following security best-practices, hardening your cluster, and having an understanding of high-risk elements in your environment will go a long way towards protecting you against bad actors successfully exploiting vulnerabilities.