Every CVE Search/ Get API key

CVE-2026-61672

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement

7.1 HighFix available

CVE-2026-61672 is a high vulnerability (CVSS 7.1) in Projectcapsule Capsule, published September 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.33%, the 26th percentile. Fixed in github.com/projectcapsule/capsule 0.13.7.

Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.7, ForbiddenListSpec.ExactMatch in pkg/api/forbidden_list.go sorts denied metadata keys case-insensitively and then uses sort.SearchStrings, which assumes byte-order sorting. When an administrator's forbidden list mixes capitalized and lowercase keys or otherwise has different case-insensitive and byte ordering, the binary search can return false for a key that is present. An authenticated tenant owner can then pass the missed key through api.ValidateForbidden and bypass configured namespace, Service, or delegated node metadata restrictions, potentially influencing cluster policies, network exposure, or scheduling outside the tenant boundary. Uniformly lowercase lists whose two orderings coincide are not affected. This issue is fixed in version 0.13.7.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
High
Availability
None

Exploit likelihood

0.33%Up 0.1 points since Sep 19, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.1

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement

Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.7, ForbiddenListSpec.ExactMatch in pkg/api/forbidden_list.go sorts denied metadata keys case-insensitively and then uses sort.SearchStrings, which assumes byte-order sorting. When an administrator's forbidden list mixes capitalized and lowercase keys or otherwise has different case-insensitive and byte ordering, the binary search can return false for a key that is present. An authenticated tenant owner can then pass the missed key through api.ValidateForbidden and bypass configured namespace, Service, or delegated node metadata restrictions, potentially influencing cluster policies, network exposure, or scheduling outside the tenant boundary. Uniformly lowercase lists whose two orderings coincide are not affected. This issue is fixed in version 0.13.7.

Record
CVE-2026-61672
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N
Weakness
CWE-697, CWE-863
Updated
2026-11-02
EUVDEUVD-2026-83164 7.1

Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.7, ForbiddenListSpec.ExactMatch in pkg/api/forbidden_list.go sorts denied metadata keys case-insensitively and then uses sort.SearchStrings, which assumes byte-order sorting. When an administrator's forbidden list mixes capitalized and lowercase keys or otherwise has different case-insensitive and byte ordering, the binary search can return false for a key that is present. An authenticated tenant owner can then pass the missed key through api.ValidateForbidden and bypass configured namespace, Service, or delegated node metadata restrictions, potentially influencing cluster policies, network exposure, or scheduling outside the tenant boundary. Uniformly lowercase lists whose two orderings coincide are not affected. This issue is fixed in version 0.13.7.

Record
EUVD-2026-83164
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-gjw4-3v3v-rqxg 7.1

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement

Summary

Capsule lets a cluster administrator forbid specific metadata keys that tenant owners must not place on their own resources: Tenant.spec.namespaceOptions.forbiddenLabels / forbiddenAnnotations (namespaces), Tenant.spec.serviceOptions.forbiddenLabels / forbiddenAnnotations (Services), and the cluster-wide forbidden worker-node labels/annotations. These lists are an isolation control — they exist to stop a tenant owner from setting metadata that other controllers or admission plugins key on (Pod Security Admission labels, kubernetes.io/metadata.name, LoadBalancer/externalIP service annotations, scheduler annotations, vendor labels that grant network reach, etc.). The validating webhooks enforce them through api.ValidateForbidden, which calls ForbiddenListSpec.ExactMatch(key) for every key the tenant submits.

ExactMatch is broken. It sorts the denied list case-insensitively (sort.SliceStable with a strings.ToLower comparator) and then performs a byte-order binary search (sort.SearchStrings) over the result. sort.SearchStrings is only correct on a slice sorted in plain byte-ascending order. Whenever the denied list contains an entry whose case-insensitive position differs from its byte position — which happens any time the list mixes a capitalised key with lowercase keys, because ASCII uppercase letters (0x41–0x5A) sort before lowercase (0x61–0x7A) by byte but are interleaved by ToLower — the binary search lands on the wrong index and ExactMatch returns false for a key that is literally present in the denied list. The webhook then allows the forbidden metadata.

A tenant owner (who legitimately holds patch/create rights on their own tenant-owned namespaces and Services) can therefore set a metadata key the administrator explicitly forbade, defeating the control and reaching metadata-driven cross-tenant / system effects of exactly the kind Capsule's forbidden lists are meant to prevent. The bug is deterministic, requires no race, and is present unchanged on main HEAD.

Affected code (v0.13.5)

pkg/api/forbidden_list.go — the comparison primitive:

func (in ForbiddenListSpec) ExactMatch(value string) (ok bool) {
	if len(in.Exact) > 0 {
		sort.SliceStable(in.Exact, func(i, j int) bool {
			return strings.ToLower(in.Exact[i]) < strings.ToLower(in.Exact[j]) // case-INSENSITIVE order
		})

		i := sort.SearchStrings(in.Exact, value) // binary search assuming BYTE order

		ok = i < len(in.Exact) && in.Exact[i] == value
	}

	return ok
}

sort.SearchStrings returns the smallest index i such that in.Exact[i] >= value under raw byte comparison. If the slice is not byte-sorted, that index is wrong and the subsequent in.Exact[i] == value equality check fails even though value is in the slice — a false "not forbidden".

pkg/api/forbidden_list.go — the public entry point the webhooks call:

func ValidateForbidden(metadata map[string]string, forbiddenList ForbiddenListSpec) error {
	if reflect.DeepEqual(ForbiddenListSpec{}, forbiddenList) {
		return nil
	}
	for key := range metadata {
		var forbidden, matched bool
		forbidden = forbiddenList.ExactMatch(key)   // <-- buggy
		matched = forbiddenList.RegexMatch(key)
		if forbidden || matched {
			return NewForbiddenError(key, forbiddenList)
		}
	}
	return nil
}

Reached from (all in internal/webhook/):

  • namespace/validation/user_metadata.go → validateUserMetadata → api.ValidateForbidden(labels, options.ForbiddenLabels) and api.ValidateForbidden(annotations, options.ForbiddenAnnotations).
  • service/validating.go → api.ValidateForbidden(svc.Labels, tnt.Spec.ServiceOptions.ForbiddenLabels) and ...ForbiddenAnnotations.
  • node/user_metadata.go → getForbiddenNodeLabels / getForbiddenNodeAnnotations call forbiddenLabels.ExactMatch(...) directly.

(The sibling allow-list primitive AllowedListSpec.ExactMatch in pkg/api/allowed_list.go has the identical defect,…

Record
GHSA-gjw4-3v3v-rqxg
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N
Weakness
CWE-697, CWE-863
Updated
2026-11-02
NVD 7.1

Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.7, ForbiddenListSpec.ExactMatch in pkg/api/forbidden_list.go sorts denied metadata keys case-insensitively and then uses sort.SearchStrings, which assumes byte-order sorting. When an administrator's forbidden list mixes capitalized and lowercase keys or otherwise has different case-insensitive and byte ordering, the binary search can return false for a key that is present. An authenticated tenant owner can then pass the missed key through api.ValidateForbidden and bypass configured namespace, Service, or delegated node metadata restrictions, potentially influencing cluster policies, network exposure, or scheduling outside the tenant boundary. Uniformly lowercase lists whose two orderings coincide are not affected. This issue is fixed in version 0.13.7.

Record
CVE-2026-61672
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N
Weakness
CWE-697, CWE-863
Updated
2026-11-02
OSV 7.1

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement

Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.7, ForbiddenListSpec.ExactMatch in pkg/api/forbidden_list.go sorts denied metadata keys case-insensitively and then uses sort.SearchStrings, which assumes byte-order sorting. When an administrator's forbidden list mixes capitalized and lowercase keys or otherwise has different case-insensitive and byte ordering, the binary search can return false for a key that is present. An authenticated tenant owner can then pass the missed key through api.ValidateForbidden and bypass configured namespace, Service, or delegated node metadata restrictions, potentially influencing cluster policies, network exposure, or scheduling outside the tenant boundary. Uniformly lowercase lists whose two orderings coincide are not affected. This issue is fixed in version 0.13.7.

Record
CVE-2026-61672
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N
Weakness
CWE-697, CWE-863
Updated
2026-11-02
OSVGHSA-gjw4-3v3v-rqxg 7.1

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement

Summary

Capsule lets a cluster administrator forbid specific metadata keys that tenant owners must not place on their own resources: Tenant.spec.namespaceOptions.forbiddenLabels / forbiddenAnnotations (namespaces), Tenant.spec.serviceOptions.forbiddenLabels / forbiddenAnnotations (Services), and the cluster-wide forbidden worker-node labels/annotations. These lists are an isolation control — they exist to stop a tenant owner from setting metadata that other controllers or admission plugins key on (Pod Security Admission labels, kubernetes.io/metadata.name, LoadBalancer/externalIP service annotations, scheduler annotations, vendor labels that grant network reach, etc.). The validating webhooks enforce them through api.ValidateForbidden, which calls ForbiddenListSpec.ExactMatch(key) for every key the tenant submits.

ExactMatch is broken. It sorts the denied list case-insensitively (sort.SliceStable with a strings.ToLower comparator) and then performs a byte-order binary search (sort.SearchStrings) over the result. sort.SearchStrings is only correct on a slice sorted in plain byte-ascending order. Whenever the denied list contains an entry whose case-insensitive position differs from its byte position — which happens any time the list mixes a capitalised key with lowercase keys, because ASCII uppercase letters (0x41–0x5A) sort before lowercase (0x61–0x7A) by byte but are interleaved by ToLower — the binary search lands on the wrong index and ExactMatch returns false for a key that is literally present in the denied list. The webhook then allows the forbidden metadata.

A tenant owner (who legitimately holds patch/create rights on their own tenant-owned namespaces and Services) can therefore set a metadata key the administrator explicitly forbade, defeating the control and reaching metadata-driven cross-tenant / system effects of exactly the kind Capsule's forbidden lists are meant to prevent. The bug is deterministic, requires no race, and is present unchanged on main HEAD.

Affected code (v0.13.5)

pkg/api/forbidden_list.go — the comparison primitive:

func (in ForbiddenListSpec) ExactMatch(value string) (ok bool) {
	if len(in.Exact) > 0 {
		sort.SliceStable(in.Exact, func(i, j int) bool {
			return strings.ToLower(in.Exact[i]) < strings.ToLower(in.Exact[j]) // case-INSENSITIVE order
		})

		i := sort.SearchStrings(in.Exact, value) // binary search assuming BYTE order

		ok = i < len(in.Exact) && in.Exact[i] == value
	}

	return ok
}

sort.SearchStrings returns the smallest index i such that in.Exact[i] >= value under raw byte comparison. If the slice is not byte-sorted, that index is wrong and the subsequent in.Exact[i] == value equality check fails even though value is in the slice — a false "not forbidden".

pkg/api/forbidden_list.go — the public entry point the webhooks call:

func ValidateForbidden(metadata map[string]string, forbiddenList ForbiddenListSpec) error {
	if reflect.DeepEqual(ForbiddenListSpec{}, forbiddenList) {
		return nil
	}
	for key := range metadata {
		var forbidden, matched bool
		forbidden = forbiddenList.ExactMatch(key)   // <-- buggy
		matched = forbiddenList.RegexMatch(key)
		if forbidden || matched {
			return NewForbiddenError(key, forbiddenList)
		}
	}
	return nil
}

Reached from (all in internal/webhook/):

  • namespace/validation/user_metadata.go → validateUserMetadata → api.ValidateForbidden(labels, options.ForbiddenLabels) and api.ValidateForbidden(annotations, options.ForbiddenAnnotations).
  • service/validating.go → api.ValidateForbidden(svc.Labels, tnt.Spec.ServiceOptions.ForbiddenLabels) and ...ForbiddenAnnotations.
  • node/user_metadata.go → getForbiddenNodeLabels / getForbiddenNodeAnnotations call forbiddenLabels.ExactMatch(...) directly.

(The sibling allow-list primitive AllowedListSpec.ExactMatch in pkg/api/allowed_list.go has the identical defect,…

Record
GHSA-gjw4-3v3v-rqxg
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N
Weakness
CWE-697, CWE-863
Updated
2026-11-02
OSVGO-2026-6520 No score

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement in github.com/projectcapsule/capsule

Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement in github.com/projectcapsule/capsule

Record
GO-2026-6520
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/projectcapsule/capsule
Go
through 0.13.6
0.13.7
github.com/projectcapsule/capsule
Go
before 0.13.7
0.13.7

History

History
WhenChangedSources
2026-11-02createdCVE List, EUVD, GitHub Advisories, NVD, OSV

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open