返回
2026/11/10
Kyverno CVE-2026-124440:当策略引擎成为通往集群管理员权限的绕过路径
在 Kyverno 1.19.1 中,仅被允许在单个命名空间内编写策略的租户可以获得集群管理员权限。本文说明绕过原理以及升级前需要检查的事项。
许多团队使用 Kyverno 来隔离 Kubernetes 租户。在 API 服务器存储对象之前,Kyverno 会根据策略检查每一个对象;它还可以允许命名空间所有者为自己的命名空间编写策略。2026 年 11 月 8 日公布的 CVE-2026-124440 表明,这种权限委派可能失效。在 Kyverno 1.19.1 中,只能在自身命名空间内创建策略的租户,可以让 Kyverno 在该命名空间之外执行操作,并一步步获得集群管理员权限。
自 10 月 20 日起,Kyverno 1.19.2 已提供修复。未升级到该版本的集群仍然存在风险。本文将说明问题出在哪里、权限提升如何实现,以及在您自己的集群中应检查哪些内容。
要点
- CVE-2026-124440(GitHub 安全公告 GHSA-39w8-hv5g-f73w)影响 Kyverno 1.19.1,已在 1.19.2 中修复。CVE 记录给出的评分为 CVSS 4.0 下 9.4、CVSS 3.1 下 9.9。
- 攻击者只需拥有在自身命名空间内创建命名空间级 Kyverno Policy 的权限。
- 策略中的 apiCall 以 Kyverno 的 admission-controller ServiceAccount 身份运行,该 ServiceAccount 可以读取其他命名空间,并能创建集群范围的准入 Webhook。这条路径最终通向集群管理员权限。
- 安全公告未提供临时缓解措施。请升级到 1.19.2,然后审查哪些主体可以创建策略,以及集群中存在哪些 Webhook。
- 在我们查阅的资料中,尚无在野利用的报告。
命名空间限制(namespace clamp)原本的作用
Kyverno 策略在评估请求时可以从 Kubernetes API 获取数据。这一功能称为 apiCall:规则指定一个 urlPath,Kyverno 调用 API 服务器,并将结果提供给规则使用。该调用使用的是 Kyverno 自身的 ServiceAccount,而不是策略编写者的权限。
对于由平台管理员编写的集群级 ClusterPolicy,这是预期行为。但对于可以允许租户编写的命名空间级 Policy,这就构成了风险。此前的安全公告(GHSA-c5qq-7g2q-cpqp 和 GHSA-5qq8-67g6-4h2w)表明,命名空间级 Policy 可以利用 apiCall 读取其他命名空间,或写入集群级对象。2026 年 9 月 10 日发布的 Kyverno 1.19.1 增加了”命名空间限制”(namespace clamp):在执行调用之前,Kyverno 会检查路径是否仍处于策略自身的命名空间之内。
检查与实际操作在哪里出现分歧
1.19.1 中的命名空间限制并没有检查实际发送的字符串。根据安全公告,它会先解码 urlPath 中的百分号编码,再对结果进行规范化(以解析 .. 路径段),然后在这份清理后的副本上检查命名空间。而请求本身发送的仍是原始、未经处理的路径。
只要解码成功,这种做法就没有问题。但如果路径中包含格式错误的百分号转义,例如末尾查询字符串中的单独 %,解码就会失败。此时,1.19.1 的代码会退而检查原始的、仍处于编码状态的字符串。API 服务器没有这样的回退逻辑:它会完整解码路径并路由请求。于是,命名空间限制看到的是租户自己的命名空间,而 API 服务器看到的是经过编码的 .. 路径段,这些路径段会跳出该命名空间,进入另一个命名空间或集群级资源集合。
安全公告强调,这是一类输入,而不是某一个特定的攻击载荷。仅拦截某个字面字符串无法堵住这个漏洞。根本的修复方法是让校验的路径与执行的路径完全一致。
1.19.2 正是这样做的。根据我们对 1.19.2 源代码的阅读,Kyverno 现在会为路径生成唯一的规范形式,拒绝无法规范化的路径,在该形式上检查命名空间,并将同一形式发送给 API 服务器。同一版本中修复的另一个相关问题 CVE-2026-122310(GHSA-3xfv-vq8x-qhg4),通过将 ../ 路径段隐藏在 # 或 ? 之后,利用了清理后检查与原始请求之间的同一分歧。它是一个独立的 CVE,有自己的记录。
权限提升链:逐步分析
报告者在 Kubernetes 1.31 上演示了这一攻击链,环境中的 Kyverno 1.19.1 使用官方 Helm chart 及默认值安装。
- 创建命名空间级 Policy。租户唯一的权限是在自身命名空间内创建
policies.kyverno.io。该策略包含一个apiCall,其路径能够通过命名空间限制,却被路由到其他位置。 - 触发策略。创建任何与该策略匹配的普通对象,例如租户命名空间中的一个 ConfigMap,都会使 Kyverno 评估该规则,并以其 admission-controller ServiceAccount 身份执行调用。
- 跨命名空间读取。使用同样的技术可以读取其他命名空间中的对象;如果 Kyverno 部署被允许读取 Secrets,Secrets 也包括在内。
- 写入集群范围的 Webhook。该 ServiceAccount 可以创建 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration,因此租户可以注册自己的 Webhook,进而在所有命名空间中拦截并改写准入请求。
- 获得集群管理员权限。安全公告描述了如何利用这样的 Webhook 篡改在 kube-system 中创建的 Pod,并由此授予租户 cluster-admin 权限。其结果是机密性、完整性和可用性全部丧失。
整个过程无需用户交互,Webhook 会在正常的集群活动中被触发。
受影响范围
CVE 记录将 Kyverno 1.19.1 列为受影响版本,1.19.2 列为不受影响版本。1.19.1 之前的版本不受此绕过问题影响,因为它们根本没有命名空间限制。但这些版本受到命名空间限制原本要修复的早期安全公告所述问题的影响,因此停留在旧版本并不是安全的替代方案。允许命名空间所有者、CI 流水线或自助服务门户创建 Kyverno Policy 的环境风险最高。
Kyverno 1.19.2 于 2026 年 10 月 20 日发布,其发布说明列出了 24 个 GitHub 安全公告:9 个严重、14 个高危、1 个中危。其中数个涉及 API 路径校验和命名空间隔离。本安全公告于三天后的 10 月 23 日发布,但安全公告和 CVE 记录都将 1.19.2 列为修复版本。每个安全公告都有自己的标识符,因此请逐一核对,而不要把这一批公告当作单个 CVE 处理。
在您自己的集群中应检查什么
首先,确认实际运行的 Kyverno 版本,而不是 Git 仓库中记录的版本:
kubectl get deployments -n kyverno -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.template.spec.containers[*].image}{"\n"}{end}'
如果有任何镜像标签为 v1.19.1,请立即规划升级到 1.19.2。然后检查以下四项:
- 谁可以创建命名空间级 Policy。直接使用租户身份进行测试,并查找授予
policies.kyverno.io的角色,包括向内置 admin 和 edit 角色追加权限的聚合 ClusterRole。 - 使用 apiCall 的现有策略。列出这些策略并审查每个
urlPath,尤其是包含%、..、?或#的路径。 - Webhook 配置。将列表与预期配置进行对比。Kyverno 会创建自己的 Webhook,因此请重点关注无法识别的名称和近期的创建时间。
- 审计日志。查找 Kyverno admission-controller ServiceAccount 发出的、偏离其常规模式的请求,例如创建 Webhook 配置或读取 Secrets。
kubectl auth can-i create policies.kyverno.io -n team-a --as=system:serviceaccount:team-a:default
kubectl get policies.kyverno.io -A -o json | jq -r '.items[] | select([.spec.rules[]?.context[]? | select(.apiCall)] | length > 0) | "\(.metadata.namespace)/\(.metadata.name)"'
kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations -o custom-columns=NAME:.metadata.name,CREATED:.metadata.creationTimestamp
请将 team-a 替换为您自己的租户命名空间和身份。如果在运行过 1.19.1 的集群上发现无法解释的 Webhook,请将其视为可能的安全事件:在删除任何内容之前先保全审计日志。
更广泛的教训:审计执行者本身
准入控制器、策略引擎和 Operator 往往是集群中权限最高的组件。它们需要广泛的权限才能完成工作,租户每天也都在与它们交互。这使它们成为极具吸引力的攻击目标。在本案例中,租户隔离模型依赖于一项检查,而检查与请求对同一个解码步骤处理方式不同,就足以将其攻破。
对于私有云和多租户 Kubernetes 平台,以下三个习惯会有所帮助。将策略引擎视为攻击面的一部分,像跟踪 Kubernetes 版本一样密切跟踪其安全版本。只为其 ServiceAccount 授予必要的权限,例如除非策略确实需要,否则不授予 Secret 读取权限。并审查租户可以通过权限委派使用哪些功能,因为以平台权限运行的功能会把租户的输入变成平台的操作。
参考资料
- Kyverno 安全公告 GHSA-39w8-hv5g-f73w:通过格式错误的百分号转义绕过 v1.19.1 apiCall 命名空间限制,提升至 cluster-admin 权限
- CVE 记录:CVE-2026-124440
- VulnCheck 安全公告:通过绕过 apiCall 命名空间限制实现的 Kyverno 1.19.1 权限提升
- 同一版本中的相关修复 CVE-2026-122310:VulnCheck 安全公告和GHSA-3xfv-vq8x-qhg4
- Kyverno v1.19.2 发布说明:github.com/kyverno/kyverno/releases/tag/v1.19.2
Global
Japan
Korea
Taiwan
Vietnam
Thailand
Indonesia
Portugal
Spain
France
Germany
Egypt
Russia