安全性:Yaml Bomb:用户可以通过发送configmap重新启动kube-api

max*_*ang 18 yaml kubernetes

创建yaml-bomb.yaml文件:

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
Run Code Online (Sandbox Code Playgroud)

ConfigMap通过cmd 将创建请求发送到Kubernetes API kubectl apply -f yaml-bomb.yaml

kube-api CPU /内存使用率很高,甚至在以后重新启动时也是如此。

我们如何防止这种炸弹?

fly*_*lyx 14

这是十亿个笑声攻击,只能在YAML处理器中修复。

请注意,此处的维基百科是错误的

对于可能包含引用的任何文件格式,都应存在“十亿个笑声”攻击,例如,此YAML炸弹:

问题不在于文件格式包含引用。是处理器扩展它们。这与YAML规范的精神背道而驰,YAML规范说锚定用于实际上是从多个位置引用的节点。在加载的数据中,锚点和别名应成为对同一对象的多个引用,而不是将别名扩展到锚定节点的副本。

例如,在粘贴代码段时,比较在线PyYAML解析器在线NimYAML解析器的行为(完整披露:我的工作)。PyYAML不会响应,因为扩展别名会占用内存,而NimYAML不会扩展别名,因此响应很快。

Kubernetes遭受这个问题之苦令人惊讶。我一直以为,因为它是用Go语言编写的,因此他们能够正确处理引用。您必须向他们提交错误才能更正此错误。


Ror*_*une 6

我可以想到一些可能的缓解方法,尽管正如@flyx所说,此处的真正解决方法是在Kubernetes使用的YAML解析库中。

有趣的是,在我的本地计算机上的Kubernetes集群上运行此脚本,显示CPU峰值位于客户端(这是搅动CPU的kubectl进程),而不是服务器端。

如果问题出在服务器端,则可能的缓解方法是,使用RBAC来最大程度地减少对ConfigMap创建的访问,并可能使用诸如OPA之类的接纳控制器来检查清单,然后再将其应用于群集。

Kubernetes安全漏洞响应团队可能应该提出这一建议,以便可以实施适当的修复。

编辑 -我认为问题出在哪里,可能取决于所使用的群集版本。服务器端应用在1.16中逐步升级到Beta(默认情况下应启用)。因此,在1.16群集上,这可能会影响服务器端而不是客户端。

编辑 -只需设置一个1.16群集,仍然在kubectl中将CPU使用情况显示为客户端...

编辑 -我为此提出了一个问题,这里还确认可以通过使用curl而不是来在服务器端实现DoSkubectl

最终编辑 -已为此分配了CVE(CVE-2019-11253),并已在Kubernetes 1.13+中修复。该修复程序还已应用于此处的基础YAML解析库因此,只要其他Go程序使用的是最新版本,也应该可以。