Security | Jan 08, 2021

Kubernetes Security: Stop Blind SSRF with Policy as Code (CVE-2020-8555)

Kubernetes Security: Stop Blind SSRF with Policy as Code (CVE-2020-8555)

Kubernetes security, as stated in earlier blogs, is complex to manage and needs a holistic security approach. One of these approaches that can help shift security left is to use policy as code tools like Terrascan. Ever since Terrascan gained the ability to scan k8s configurations, we have been actively looking for the latest vulnerabilities so we can help developers mitigate them using Policy as Code.

Kubernetes Security Lists

The Kubernetes-security-announce group has been at the top of our list for the latest advisories and CVEs related to Kubernetes. We’ve covered several recent ones in our blog, and this post focuses on another issue: CVE-2020-8555, which enables an adversary to exploit a Server Side Request Forgery (SSRF) vulnerability and cause kube-controller-manager to make GET or POST requests on behalf of the attacker.

This vulnerability affects the kube-controller-manager. The vulnerable versions are exploitable provided an attacker can create a pod and attach certain volumes or can create a StorageClass. Under these conditions, the attacker can perform an SSRF attack through the kube-controller-manager. To mitigate this risk, affected users should disallow the creation of pods which mount these volume types (GlusterFS, Quobyte, StorageOS, ScaleIO) by untrusted users, and restrict write permissions for StorageClass. This mitigation can be achieved by leveraging the capabilities of policy as code.

CVE-2020-8555

Affected versions of Kube-Controller-Manager:

V1.18.0, v1.17.0 – v1.17.4, v1.16.0 – v1.16.8, and versions earlier than v1.15.11

Impact:

Half Blind SSRF

CVSS Score:

6.3 Medium (3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N)

Let’s consider the following attack scenario: you are running one of the affected versions of kube-controller-manager, and:

  1. An adversary creates a pod in your cluster
  2. The adversary mounts a GlusterFS volume, which is subject to the vulnerability
  3. Once the vulnerable volume is mounted, the kube-controller-manager will make GET or POST requests without an attacker-controlled request body from the master’s host network

The following YAML could be used, for example:

apiVersion: v1
kind: Pod
metadata:
 name: glusterfs-vol-example
spec:
 hostPID: true
 containers:
   - name: busybox
     image: busybox
 volumes:
 - name: glusterfsvol
   glusterfs:
     endpoints: glusterfs-cluster
     path: kube_vol
     readOnly: true
 

As mentioned in the github discussion linked above, this will exploit the vulnerable kube-controller-manager and allow certain users to access endpoints within the master’s host network, such as link-local or loopback services.

The end result is a leak of up to 500 bytes of arbitrary information (per request) from these endpoints.

Mitigation

The latest releases of Kubernetes are patched against this vulnerability. However, before upgrade, the following mitigation options can be implemented:

  1. Restricting the mounting of certain volume types (GlusterFS, Quobyte, StorageOS, ScaleIO).
  2. Restricting StorageClass write permissions through RBAC.

Restricting the volume mount using Terrascan

To help developers implement these mitigations, and to alert users to the presence of this risk, we recently added a policy in our open source Terrascan offering which leverages the Open Policy Agent.

Kubernetes provides for different options to define a pod spec, such as Deployment, ReplicaSet, Job, DaemonSet, StatefulSet, and Cronjob. The policy in Terrascan will protect against all the relevant options, with full details available in the repository.  Here’s a simplified snippet of the Rego code which implements the 1st mitigation option:

package accurics
 
#rule for pod
disAllowedVolumes[pod.id] {
   pod := input.kubernetes_pod[_]
   volume_types := {x | pod.config.spec.volumes[_][x]; x != "name"}
   volNotAllowed(volume_types[_])
}
 
volNotAllowed(field) {
   affected_volumes := ["glusterfs", "quobyte", "storageos", "scaleIO"]
   field == affected_volumes[_]
}
 

This will identify all volumes mounted to the pod and  throw a violation if any such volumes are of the affected types.  If we were to run Terrascan on the example YAML above, for example, we would see the following output:

Kubernetes security: Terrascan stops CVE-2020-8555

Suppose you are unable to upgrade and you need to continue using a version of Kubernetes that is vulnerable to this problem. In that case, policy as code tools such as Terrascan can be run in your development pipelines to effectively identify configurations that are susceptible to this vulnerability before they are deployed.  You can also leverage policy as code in runtime controls such as admission controllers to protect your cluster in runtime.

Cloud Native Security with Kubernetes Mutating Admission Controller

Kubernetes security: preventing man in the middle with policy as code

AWS Cloud Security – Protecting Against SSRF

We use cookies to ensure you get the best experience on our website. By continuing to browse this site, you acknowledge the use of cookies.