Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Security: Yaml Bomb: user can restart kube-api by sending configmap

Create yaml-bomb.yaml file:

apiVersion: v1
data:
  a: &a ["web","web","web","web","web","web","web","web","web"]
  b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
  c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
  d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
  e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
  f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
  g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
  h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
  i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
kind: ConfigMap
metadata:
  name: yaml-bomb
  namespace: default

Send ConfigMap creation request to Kubernetes API by cmd kubectl apply -f yaml-bomb.yaml.

kube-api CPU/memory usage are very high, even later are getting restarted.

How do we prevent such yaml-bomb?

like image 209
maxwell jiang Avatar asked Sep 27 '19 06:09

maxwell jiang


3 Answers

This is a billion laughts attack and can only be fixed in the YAML processor.

Note that the Wikipedia is wrong here when it says

A "Billion laughs" attack should exist for any file format that can contain references, for example this YAML bomb:

The problem is not that the file format contains references; it is the processor expanding them. This is against the spirit of the YAML spec which says that anchors are used for nodes that are actually referred to from multiple places. In the loaded data, anchors & aliases should become multiple references to the same object instead of the alias being expanded to a copy of the anchored node.

As an example, compare the behavior of the online PyYAML parser and the online NimYAML parser (full disclosure: my work) when you paste your code snippet. PyYAML won't respond because of the memory load from expanding aliases, while NimYAML doesn't expand the aliases and therefore responds quickly.

It's astonishing that Kubernetes suffers from this problem; I would have assumed since it's written in Go that they are able to properly handle references. You have to file a bug with them to get this fixed.

like image 159
flyx Avatar answered Nov 20 '22 01:11

flyx


There's a couple of possible mitigations I could think of although as @flyx says the real fix here would be in the YAML parsing library used by Kubernetes.

Interestingly running this on a Kubernetes cluster on my local machine showed the CPU spike to be client-side (it's the kubectl process churning CPU) rather than server side.

If the issue was server side, then possible mitigations would be to use RBAC to minimize access to ConfigMap creation, and potentially to use an admission controller like OPA to review manifests before they are applied to the cluster.

This should probably be raised with the Kubernetes security vulnerability response team so that a proper fix can be implemented.

EDIT - I think where the problem manifests, might be down to the cluster version used. Server-side apply graduated to beta (should be enabled by default) in 1.16. So on a 1.16 cluster perhaps this would hit server side instead of client side.

EDIT - Just setup a 1.16 cluster, still showing the CPU usage as client-side in kubectl...

EDIT - I've filed an issue for this here also confirmed that the DoS can be achieved server-side by using curl instead of kubectl

Final EDIT - This got assigned a CVE (CVE-2019-11253) and is being fixed in Kubernetes 1.13+ . The fix has also been applied to the underlying YAML parsing lib here so any other Go programs should be ok as long as they're using an up to date version.


like image 22
Rory McCune Avatar answered Nov 20 '22 03:11

Rory McCune


There was a TrustCom19 paper studying vulnerabilities in YAML parsers for different languages, it found that most parsers have some issues, so this is common and there are several recent CVEs in this space (details in paper: Laughter in the Wild: A Study into DoS Vulnerabilities in YAML Libraries, TrustCom19. Preprint: https://www.researchgate.net/publication/333505459_Laughter_in_the_Wild_A_Study_into_DoS_Vulnerabilities_in_YAML_Libraries

like image 1
jens Avatar answered Nov 20 '22 03:11

jens