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

Kubernetes 安全性:Yaml炸弹:用户可以通过发送configmap重新启动kube api,kubernetes,yaml,Kubernetes,Yaml,创建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

创建
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
通过cmd
kubectl apply-f yaml bomb.yaml向Kubernetes API发送
ConfigMap
创建请求

kube-api
CPU/内存使用率非常高,甚至以后都会重新启动

如何防止此类yaml炸弹?

这是一个问题,只能在yaml处理器中修复

请注意,维基百科在这里说的是错误的

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

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

例如,在粘贴代码片段时,比较和(完全公开:我的工作)的行为。PyYAML不会响应,因为扩展别名会带来内存负载,而nimyml不会扩展别名,因此响应速度很快


令人惊讶的是,库伯内特斯受到了这个问题的困扰;我会假设,因为它是用Go编写的,所以它们能够正确地处理引用。你必须向他们提交一个bug来修复这个问题。

我可以考虑一些可能的缓解措施,尽管@flyx说真正的修复方法是Kubernetes使用的YAML解析库

有趣的是,在本地机器上的Kubernetes集群上运行这个程序,显示CPU峰值是客户端(这是kubectl进程搅动CPU)而不是服务器端

如果问题是服务器端的,那么可能的缓解措施是使用RBAC最大限度地减少对ConfigMap创建的访问,并可能使用准入控制器(如在将清单应用到集群之前检查清单)

这可能应该通过提出,以便能够实现适当的修复

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

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

EDIT-我已经为此提交了一个问题,并确认可以通过使用
curl
而不是
kubectl
在服务器端实现DoS

最终编辑-已分配CVE(CVE-2019-11253)并在Kubernetes 1.13+中修复。该修复程序还应用于底层YAML解析库,因此任何其他Go程序只要使用最新版本,都应该是正常的



有一篇TrustCom19论文研究了不同语言的YAML解析器中的漏洞,它发现大多数解析器都存在一些问题,因此这是常见的,最近在这一领域出现了一些CVE(详细内容见论文:《野外的笑声:对YAML库中DoS漏洞的研究》,TrustCom19)。
预印本:

我的同事检查了对我们小型pet集群(3个节点,16 GB RAM,k8s 1.15.2)的影响,我们只能看到60%的cpu使用率(只有一个核心)而且没有明显的ram使用率增加,还有来自kubectl的堆栈跟踪,其中包含进程内存已耗尽的信息。具有
kubectl
访问权限的某个用户几乎可以完全控制您的集群。他们不需要“聪明”为了削弱它。所以这只是学术上的兴趣。我投票将这个问题作为离题题来结束,因为它看起来更像kubernetes问题,最好将它发布到kubernetes问题跟踪器上。@Raedwald是高度可配置的。只有当你是绑定到
ClusterRole
clus的组的一部分时,你才能获得超级用户访问权限管理员