VYPR
Critical severity9.0OSV Advisory· Published Aug 18, 2025· Updated Apr 15, 2026

CVE-2025-55205

CVE-2025-55205

Description

Capsule is a multi-tenancy and policy-based framework for Kubernetes. A namespace label injection vulnerability in Capsule v0.10.3 and earlier allows authenticated tenant users to inject arbitrary labels into system namespaces (kube-system, default, capsule-system), bypassing multi-tenant isolation and potentially accessing cross-tenant resources through TenantResource selectors. This vulnerability enables privilege escalation and violates the fundamental security boundaries that Capsule is designed to enforce. This vulnerability is fixed in 0.10.4.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/projectcapsule/capsuleGo
< 0.10.40.10.4

Affected products

1

Patches

1
e1f47feade6e

Merge commit from fork

https://github.com/projectcapsule/capsuleOliver BählerAug 14, 2025via ghsa
2 files changed · +41 7
  • e2e/namespace_hijacking_test.go+35 1 modified
    @@ -54,7 +54,7 @@ var _ = Describe("creating several Namespaces for a Tenant", Label("namespace"),
     
     	})
     
    -	It("Can't hijack offlimits namespace", func() {
    +	It("Can't hijack offlimits namespace (Ownerreferences)", func() {
     		tenant := &capsulev1beta2.Tenant{}
     		Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt.Name}, tenant)).Should(Succeed())
     
    @@ -72,6 +72,40 @@ var _ = Describe("creating several Namespaces for a Tenant", Label("namespace"),
     		}
     	})
     
    +	It("Can't hijack offlimits namespace (Labels)", func() {
    +		tenant := &capsulev1beta2.Tenant{}
    +		Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt.Name}, tenant)).Should(Succeed())
    +
    +		// Get the namespace
    +		Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: kubeSystem.GetName()}, kubeSystem)).Should(Succeed())
    +
    +		for _, owner := range tnt.Spec.Owners {
    +			cs := ownerClient(owner)
    +
    +			patch := []byte(fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, "capsule.clastix.io/tenant", tenant.GetName()))
    +
    +			_, err := cs.CoreV1().Namespaces().Patch(context.TODO(), kubeSystem.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{})
    +			Expect(err).To(HaveOccurred())
    +		}
    +	})
    +
    +	It("Can't hijack offlimits namespace (Annotations)", func() {
    +		tenant := &capsulev1beta2.Tenant{}
    +		Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: tnt.Name}, tenant)).Should(Succeed())
    +
    +		// Get the namespace
    +		Expect(k8sClient.Get(context.TODO(), types.NamespacedName{Name: kubeSystem.GetName()}, kubeSystem)).Should(Succeed())
    +
    +		for _, owner := range tnt.Spec.Owners {
    +			cs := ownerClient(owner)
    +
    +			patch := []byte(fmt.Sprintf(`{"metadata":{"annotations":{"%s":"%s"}}}`, "capsule.clastix.io/tenant", tenant.GetName()))
    +
    +			_, err := cs.CoreV1().Namespaces().Patch(context.TODO(), kubeSystem.Name, types.StrategicMergePatchType, patch, metav1.PatchOptions{})
    +			Expect(err).To(HaveOccurred())
    +		}
    +	})
    +
     	It("Owners can create and attempt to patch new namespaces but patches should not be applied", func() {
     		for _, owner := range tnt.Spec.Owners {
     			cs := ownerClient(owner)
    
  • pkg/webhook/namespace/validation/patch.go+6 6 modified
    @@ -66,14 +66,14 @@ func (r *patchHandler) OnUpdate(c client.Client, decoder admission.Decoder, reco
     				return &response
     			}
     
    -			if !utils.IsTenantOwner(tnt.Spec.Owners, req.UserInfo) {
    -				recorder.Eventf(tnt, corev1.EventTypeWarning, "NamespacePatch", e)
    -				response := admission.Denied(e)
    -
    -				return &response
    +			if utils.IsTenantOwner(tnt.Spec.Owners, req.UserInfo) {
    +				return nil
     			}
     		}
     
    -		return nil
    +		recorder.Eventf(ns, corev1.EventTypeWarning, "NamespacePatch", e)
    +		response := admission.Denied(e)
    +
    +		return &response
     	}
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.