{"id":"CVE-2026-65834","revision":null,"records":[{"revision":"3e4a58f8236b4a519ee63b173a54dead","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-65834","aliases":[],"title":"Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing MustCompile panic on all Node admission requests","description":"Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.8, CapsuleConfiguration.Spec.NodeMetadata.ForbiddenLabels.Regex and CapsuleConfiguration.Spec.NodeMetadata.ForbiddenAnnotations.Regex were not validated by the configuration admission webhook, allowing a Cluster Admin to store a malformed regex that later reached regexp.MustCompile in pkg/api/forbidden_list.go through internal/webhook/node/user_metadata.go and crashed the node admission webhook on Node create, update, or patch requests. This issue is fixed in version 0.13.8.","state":0,"publishedAt":"2026-07-30T19:48:55.027+00:00","modifiedAt":"2026-07-31T11:29:43.998+00:00","affected":[{"ecosystem":"Vendor product","name":"capsule","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"projectcapsule\",\n                    \"product\": \"capsule\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 0.13.8\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:N/A:H","score":6.8,"severity":"MEDIUM"}],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-68cj-mvg9-rgm2","https://github.com/projectcapsule/capsule/releases/tag/v0.13.8"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-65834","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-65834","identifiers":["CVE-2026-65834"]},"retained":false,"historicalAffected":[]},{"revision":"f9afb7ae26d648bb89c46c7620d4dd34","observedAt":"2026-10-25T15:18:45.851+00:00","statement":{"source":"nvd","id":"CVE-2026-65834","aliases":[],"title":"Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.8, CapsuleConfiguration.Spec.NodeMetadata.ForbiddenLabels.Regex and CapsuleConfiguration.Spec.NodeMetadata.ForbiddenAnnotations.Regex were not validated by …","description":"Capsule is a multi-tenancy and policy-based framework for Kubernetes. Prior to 0.13.8, CapsuleConfiguration.Spec.NodeMetadata.ForbiddenLabels.Regex and CapsuleConfiguration.Spec.NodeMetadata.ForbiddenAnnotations.Regex were not validated by the configuration admission webhook, allowing a Cluster Admin to store a malformed regex that later reached regexp.MustCompile in pkg/api/forbidden_list.go through internal/webhook/node/user_metadata.go and crashed the node admission webhook on Node create, update, or patch requests. This issue is fixed in version 0.13.8.","state":0,"publishedAt":"2026-07-30T20:18:13.107+00:00","modifiedAt":"2026-10-23T22:10:00.16+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:N/A:H","score":6.8,"severity":"MEDIUM"}],"references":["https://github.com/projectcapsule/capsule/releases/tag/v0.13.8","https://github.com/projectcapsule/capsule/security/advisories/GHSA-68cj-mvg9-rgm2"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-65834","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-20","CWE-248"],"productCriteria":[],"sourceDates":{"published":"2026-07-30T20:18:13.107","lastModified":"2026-10-23T22:10:00.160"},"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-65834","identifiers":["CVE-2026-65834"]},"retained":false,"historicalAffected":[]},{"revision":"66d35bf42aa046368d18a13964742665","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-68cj-mvg9-rgm2","aliases":["CVE-2026-65834","GO-2026-6155"],"title":"Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing MustCompile panic on all Node admission requests","description":"### Summary\n\n`CapsuleConfiguration.Spec.NodeMetadata.ForbiddenLabels.Regex` and `ForbiddenAnnotations.Regex` are never validated by any admission webhook. A Cluster Admin can persist a malformed regex to etcd without being blocked. Once stored, every Node `CREATE`, `UPDATE`, or `PATCH` request triggers `regexp.MustCompile()` in `pkg/api/forbidden_list.go:36`, which **panics** and crashes the node admission webhook — causing a cluster-wide Denial of Service for all Node operations.\n\n### Root cause\n\n`internal/webhook/tenant/validation/` contains dedicated regex validators for every Tenant regex field (hostname, storageclass, ingressclass, containerregistry, etc.). `internal/webhook/cfg/` contains **no regex validator at all** — only `owners.go`, `serviceaccount.go`, and `warnings.go`.\n\nThe downstream consumer `internal/webhook/node/user_metadata.go` calls:\n```go\n// line 131\nmatched = forbiddenLabels.RegexMatch(label)\n// line 150\nmatched = forbiddenAnnotations.RegexMatch(annotation)\n```\n\nWhich routes to `pkg/api/forbidden_list.go:36`:\n```go\nfunc (in ForbiddenListSpec) RegexMatch(value string) (ok bool) {\n    if len(in.Regex) > 0 {\n        ok = regexp.MustCompile(in.Regex).MatchString(value) // ← panics on invalid regex\n    }\n    return ok\n}\n```\n\nUnlike `regexp.Compile`, `regexp.MustCompile` panics instead of returning an error. Since no webhook validates the `CapsuleConfiguration` regex fields before storage, a malformed value reaches `MustCompile` on every Node admission request.\n\n### Comparison with existing CVEs\n\n`GHSA-f94q-w3w8-cj67` and `GHSA-gxjc-74v5-3vx3` affect individual Tenant fields — their validators existed but checked the wrong field. This issue is different: **no validator exists at all** for `CapsuleConfiguration` regex fields, and the blast radius is cluster-wide (all Nodes), not scoped to one tenant.\n\n### PoC\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"regexp\"\n)\n\ntype ForbiddenListSpec struct{ Regex string }\n\n// Exact copy of pkg/api/forbidden_list.go:34-38\nfunc (in ForbiddenListSpec) RegexMatch(value string) bool {\n    if len(in.Regex) > 0 {\n        return regexp.MustCompile(in.Regex).MatchString(value)\n    }\n    return false\n}\n\nfunc main() {\n    // 1. cfg webhook has no validator → invalid regex stored in etcd\n    // (no webhook in internal/webhook/cfg/ checks regex fields)\n\n    // 2. Stored malformed regex loaded from CapsuleConfiguration\n    forbidden := ForbiddenListSpec{Regex: `[invalid-regex(`}\n\n    // 3. node/user_metadata.go:131 called on every Node admission request\n    defer func() {\n        if r := recover(); r != nil {\n            fmt.Printf(\"PANIC: %v\\n\", r)\n            // Output: PANIC: regexp: Compile(`[invalid-regex(`): error parsing regexp: missing closing ]\n        }\n    }()\n    forbidden.RegexMatch(\"kubernetes.io/hostname\")\n}\n```\n\nExpected output:\n```\nPANIC: regexp: Compile(`[invalid-regex(`): error parsing regexp: missing closing ]: `[invalid-regex(`\n```\n\n### Fix\n Add a `node_metadata_regex.go` handler to `internal/webhook/cfg/` following the same pattern as `forbidden_annotations_regex.go`:\n\n  ```go\n  package cfg\n\n  import (\n      \"context\"\n      \"regexp\"\n\n      \"sigs.k8s.io/controller-runtime/pkg/client\"\n      \"sigs.k8s.io/controller-runtime/pkg/webhook/admission\"\n\n      capsulev1beta2 \"github.com/projectcapsule/capsule/api/v1beta2\"\n      ad \"github.com/projectcapsule/capsule/pkg/runtime/admission\"\n      \"github.com/projectcapsule/capsule/pkg/runtime/events\"\n      \"github.com/projectcapsule/capsule/pkg/runtime/handlers\"\n  )\n\n  type nodeMetadataRegexHandler struct{}\n\n  func NodeMetadataRegexHandler() handlers.TypedHandler[*capsulev1beta2.CapsuleConfiguration] {\n      return &nodeMetadataRegexHandler{}\n  }\n\n  func (h *nodeMetadataRegexHandler) OnCreate(\n      _ client.Client,\n      _ client.Reader,\n      cfg *capsulev1beta2.CapsuleConfiguration,\n      _ admission.Decoder,\n      _ events.EventRecorder,\n  ) handlers.Func {\n      return func(_ context.Context, req admission.Request) *admission.Response {\n          return h.validate(cfg, req)\n      }\n  }\n\n  func (h *nodeMetadataRegexHandler) OnDelete(\n      client.Client,\n      client.Reader,\n      *capsulev1beta2.CapsuleConfiguration,\n      admission.Decoder,\n      events.EventRecorder,\n  ) handlers.Func {\n      return func(context.Context, admission.Request) *admission.Response {\n          return nil\n      }\n  }\n\n  func (h *nodeMetadataRegexHandler) OnUpdate(\n      _ client.Client,\n      _ client.Reader,\n      cfg *capsulev1beta2.CapsuleConfiguration,\n      _ *capsulev1beta2.CapsuleConfiguration,\n      _ admission.Decoder,\n      _ events.EventRecorder,\n  ) handlers.Func {\n      return func(_ context.Context, req admission.Request) *admission.Response {\n          return h.validate(cfg, req)\n      }\n  }\n\n  func (h *nodeMetadataRegexHandler) validate(cfg *capsulev1beta2.CapsuleConfiguration, req admission.Request) *admission.Response {\n      if cfg.Spec.NodeMetadata == nil {\n          return nil\n      }\n\n      expressions := map[string]string{\n          \"labels\":      cfg.Spec.NodeMetadata.ForbiddenLabels.Regex,\n          \"annotations\": cfg.Spec.NodeMetadata.ForbiddenAnnotations.Regex,\n      }\n\n      for scope, expression := range expressions {\n          if expression == \"\" {\n              continue\n          }\n\n          if _, err := regexp.Compile(expression); err != nil {\n              return ad.Denyf(\n                  \"unable to compile regex %q for forbidden %s: %v\",\n                  expression,\n                  scope,\n                  err,\n              )\n          }\n      }\n\n      return nil\n  }\n\n```\n```\n  Step 2: Register the handler in cmd/controller/main.go:\n\n  route.ConfigValidation(\n      cfgvalidation.Handler(cfg,\n          cfgvalidation.WarningHandler(),\n          cfgvalidation.ServiceAccountHandler(),\n          cfgvalidation.OwnerHandler(),\n          cfgvalidation.NodeMetadataRegexHandler(), // ← ADD THIS LINE\n      ),\n  ),\n```\n\n\n### Impact\n\n A Cluster Admin (or compromised admin account) can update CapsuleConfiguration\n  with a malformed NodeMetadata regex (e.g., `[invalid-regex(`). The update is\n  accepted without validation and persisted to etcd. Once stored, every subsequent\n  Node admission request triggers `regexp.MustCompile()` with the invalid pattern,\n  causing the Capsule node webhook to panic.\n\n  **Affected operations (cluster-wide):**\n  - Node labeling, annotations, and taints (`kubectl label/annotate/taint node`)\n  - Cluster autoscaler operations (cannot register or remove nodes)\n  - Cloud provider node lifecycle management (metadata sync, status updates)\n  - Node maintenance workflows (cordon, drain, uncordon)\n\n  **Severity:**\n  This is a **cluster-wide Denial of Service** affecting all Node infrastructure\n  operations. Unlike tenant-scoped CVEs (GHSA-f94q-w3w8-cj67, GHSA-gxjc-74v5-3vx3)\n  that impact only Ingress or Namespace operations within a single tenant, this\n  vulnerability blocks the entire cluster's ability to manage nodes.\n\n  The cluster cannot scale, perform maintenance, or process any node metadata\n  changes until a Cluster Admin manually corrects the CapsuleConfiguration—requiring\n  direct kubectl access with valid YAML.","state":0,"publishedAt":"2026-07-31T16:53:25+00:00","modifiedAt":"2026-08-18T15:10:36.7441949+00:00","affected":[{"ecosystem":"Go","name":"github.com/projectcapsule/capsule","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.13.8"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:N/I:N/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-68cj-mvg9-rgm2","https://nvd.nist.gov/vuln/detail/CVE-2026-65834","https://github.com/projectcapsule/capsule","https://github.com/projectcapsule/capsule/releases/tag/v0.13.8"],"sourceUrl":"https://github.com/advisories/GHSA-68cj-mvg9-rgm2","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-68cj-mvg9-rgm2","identifiers":["GHSA-68cj-mvg9-rgm2","CVE-2026-65834","GO-2026-6155"]},"retained":false,"historicalAffected":[]},{"revision":"d08b95528db04db1bcc4198e778a465a","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6155","aliases":["CVE-2026-65834","GHSA-68cj-mvg9-rgm2"],"title":"Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing MustCompile panic on all Node admission requests in github.com/projectcapsule/capsule","description":"Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing MustCompile panic on all Node admission requests in github.com/projectcapsule/capsule","state":0,"publishedAt":"2026-08-18T14:32:29+00:00","modifiedAt":"2026-08-18T15:00:16.1430716+00:00","affected":[{"ecosystem":"Go","name":"github.com/projectcapsule/capsule","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.13.8"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/projectcapsule/capsule/security/advisories/GHSA-68cj-mvg9-rgm2","https://nvd.nist.gov/vuln/detail/CVE-2026-65834","https://github.com/projectcapsule/capsule/releases/tag/v0.13.8"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6155","license":"OSV · upstream source license applies","key":"osv:GO-2026-6155","identifiers":["GO-2026-6155","CVE-2026-65834","GHSA-68cj-mvg9-rgm2"]},"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-10-26T11:36:23.2920201+00:00","complete":true,"records":1756,"lastAttemptAt":"2026-10-26T11:36:23.2920201+00:00","lastSuccessAt":"2026-10-26T11:36:23.5142731+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:23.5142748+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-5ba1945314e042c2ced14b33f3680fa71692812d925544312b218f5eb8a26e71-e7962156c388e029d9e5dbbcda79fbd40ade61bdd41d51546adb4696b3e29228","complete":true,"records":414161,"lastAttemptAt":"2026-10-26T11:36:10.3293998+00:00","lastSuccessAt":"2026-10-26T11:36:10.2537359+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:10.3293998+00:00","snapshotPublishedAt":"2026-10-26T11:28:55+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-43321610382942b8ad8c85917eab1546","complete":false,"records":4735,"lastAttemptAt":"2026-10-26T11:36:27.570174+00:00","lastSuccessAt":"2026-10-24T23:18:49.862+00:00","error":"InvalidDataException","lastVerifiedAt":"2026-10-24T23:18:49.862+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":4764,"expectedIdentifiers":13477},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-10-26T11:36:23.2920201+00:00","complete":true,"records":1093,"lastAttemptAt":"2026-10-26T11:36:23.2920201+00:00","lastSuccessAt":"2026-10-26T11:36:23.6271598+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:23.6271612+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-114096430e32489f93a3ae96f397b2db","complete":true,"records":13416,"lastAttemptAt":"2026-10-26T11:36:25.3338531+00:00","lastSuccessAt":"2026-10-26T11:36:25.326+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:25.326+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13477,"expectedIdentifiers":13477},{"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-2375a4e597279abf92e8747e140fe8da9d421877cd49cae3ac69a2cb78469b2c","complete":true,"records":9779,"lastAttemptAt":"2026-10-26T11:36:10.7420905+00:00","lastSuccessAt":"2026-10-24T13:19:53.1346702+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:10.7420905+00:00","snapshotPublishedAt":"2026-10-24T03:03:12+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-16ad89dfea13ab9e9b0108e63a759d63bd4559cc68b58491107d62ee35bbbaf2","complete":true,"records":1965,"lastAttemptAt":"2026-10-26T11:36:10.517478+00:00","lastSuccessAt":"2026-10-23T16:01:26.4487605+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:10.517478+00:00","snapshotPublishedAt":"2026-10-21T12:18:07+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-7d18ad8657bc2f95d55948e9e16b3c82a8ac06830df5ec8d356048b8420b72c3","complete":true,"records":2972,"lastAttemptAt":"2026-10-26T11:36:23.2053293+00:00","lastSuccessAt":"2026-10-26T11:36:23.0131888+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:23.2053293+00:00","snapshotPublishedAt":"2026-10-26T11:33:16+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-654e90fb44abcd729ddecf56d54c1b46ce87ca3181850e8bc65d5c8befceb659","complete":true,"records":230805,"lastAttemptAt":"2026-10-26T11:36:10.6367182+00:00","lastSuccessAt":"2026-10-26T08:22:30.1390577+00:00","error":null,"lastVerifiedAt":"2026-10-26T11:36:10.6367182+00:00","snapshotPublishedAt":"2026-10-26T07:48:28+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null}]}