{"id":"CVE-2026-53487","revision":null,"records":[{"revision":"13f852aee1aa440da96abfaae5728c51","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-53487","aliases":[],"title":"Kite has an authenticated cluster RBAC bypass in /api/v1/overview","description":"Kite is a Kubernetes dashboard. Prior to version 0.12.3, authenticated Kite users with any role can request `/api/v1/overview` for a cluster that their roles do not permit by selecting that cluster with `x-cluster-name`. The overview route is registered before `middleware.RBACMiddleware()` and `GetOverview` only checks `len(user.Roles) > 0`, so it returns aggregate Kubernetes inventory and capacity data from unauthorized clusters. Version 0.12.3 fixes the issue.","state":0,"publishedAt":"2026-08-21T21:35:41.451+00:00","modifiedAt":"2026-08-25T16:47:05.989+00:00","affected":[{"ecosystem":"Vendor product","name":"kite","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"kite-org\",\n                    \"product\": \"kite\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 0.12.3\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","score":4.3,"severity":"MEDIUM"}],"references":["https://github.com/kite-org/kite/security/advisories/GHSA-gvhc-wv3v-7pf8"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-53487","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-53487","identifiers":["CVE-2026-53487"]},"retained":false,"historicalAffected":[]},{"revision":"764dcd602c6e46058185c4b315d6134e","observedAt":"2026-11-09T12:11:27.566+00:00","statement":{"source":"euvd","id":"EUVD-2026-64181","aliases":["CVE-2026-53487","GHSA-gvhc-wv3v-7pf8"],"title":"Kite is a Kubernetes dashboard. Prior to version 0.12.3, authenticated Kite users with any role can request `/api/v1/overview` for a cluster that their roles do not permit by selecting that cluster with `x-cluster-name`. The overview route …","description":"Kite is a Kubernetes dashboard. Prior to version 0.12.3, authenticated Kite users with any role can request `/api/v1/overview` for a cluster that their roles do not permit by selecting that cluster with `x-cluster-name`. The overview route is registered before `middleware.RBACMiddleware()` and `GetOverview` only checks `len(user.Roles) > 0`, so it returns aggregate Kubernetes inventory and capacity data from unauthorized clusters. Version 0.12.3 fixes the issue.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","score":4.3,"severity":null}],"references":["https://github.com/kite-org/kite/security/advisories/GHSA-gvhc-wv3v-7pf8"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-64181","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Aug 21, 2026, 9:35:41 PM","dateUpdated":"Aug 25, 2026, 4:47:05 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-64181","identifiers":["EUVD-2026-64181","CVE-2026-53487","GHSA-gvhc-wv3v-7pf8"]},"retained":false,"historicalAffected":[]},{"revision":"1e3454f98e6f44758f0f5f24ea2249c6","observedAt":"2026-10-25T13:17:16.273+00:00","statement":{"source":"nvd","id":"CVE-2026-53487","aliases":[],"title":"Kite is a Kubernetes dashboard. Prior to version 0.12.3, authenticated Kite users with any role can request `/api/v1/overview` for a cluster that their roles do not permit by selecting that cluster with `x-cluster-name`. The overview route …","description":"Kite is a Kubernetes dashboard. Prior to version 0.12.3, authenticated Kite users with any role can request `/api/v1/overview` for a cluster that their roles do not permit by selecting that cluster with `x-cluster-name`. The overview route is registered before `middleware.RBACMiddleware()` and `GetOverview` only checks `len(user.Roles) > 0`, so it returns aggregate Kubernetes inventory and capacity data from unauthorized clusters. Version 0.12.3 fixes the issue.","state":0,"publishedAt":"2026-08-21T22:16:38.71+00:00","modifiedAt":"2026-10-12T16:10:00.22+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","score":4.3,"severity":"MEDIUM"}],"references":["https://github.com/kite-org/kite/security/advisories/GHSA-gvhc-wv3v-7pf8"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-53487","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-862"],"productCriteria":[],"sourceDates":{"published":"2026-08-21T22:16:38.710","lastModified":"2026-10-12T16:10:00.220"},"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-53487","identifiers":["CVE-2026-53487"]},"retained":false,"historicalAffected":[]},{"revision":"8e438cc77c7e4c969aeaa0cee052f402","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-gvhc-wv3v-7pf8","aliases":["CVE-2026-53487","GO-2026-5941"],"title":"Kite has an authenticated cluster RBAC bypass in /api/v1/overview","description":"## Summary\n\nAuthenticated Kite users with any role can request `/api/v1/overview` for a cluster that their roles do not permit by selecting that cluster with `x-cluster-name`. The overview route is registered before `middleware.RBACMiddleware()` and `GetOverview` only checks `len(user.Roles) > 0`, so it returns aggregate Kubernetes inventory and capacity data from unauthorized clusters.\n\nThe issue is present on current main commit `38c9bb9d4b746c0d2a8252f3c35cdfa07ab01c21` and latest release `v0.12.2` at commit `0aae35abb2d6a8adf623fe60349261aa48753ccc`.\n\n## Impact\n\nA low-privileged user who only has access to one cluster can set `x-cluster-name` to another configured cluster and retrieve aggregate inventory and resource sizing data for that cluster. The response includes total node, pod, namespace, service, CPU, and memory values. This bypasses the cluster membership boundary used elsewhere in Kite.\n\nThe validated impact is confidentiality only. I did not prove Kubernetes mutation, pod names, secret values, kubeconfig contents, or bearer token exposure through this endpoint.\n\n## Technical details\n\n`routes.go` registers `/api/v1/overview` before the global RBAC middleware is applied:\n\n- `routes.go:131-133`: `/api/v1` gets `RequireAuth()` and `ClusterMiddleware(cm)`.\n- `routes.go:135`: `/api/v1/overview` is registered.\n- `routes.go:171`: `api.Use(middleware.RBACMiddleware())` is applied only after overview and several other routes are registered.\n\n`pkg/middleware/cluster.go:21-40` accepts the target cluster name from `x-cluster-name`, query, or cookie and injects the matching `ClientSet` without checking whether the user can access that cluster.\n\n`pkg/system/handler.go:47-52` retrieves the selected cluster and user, but only rejects users with zero roles:\n\n```go\ncs := c.MustGet(\"cluster\").(*cluster.ClientSet)\nuser := c.MustGet(\"user\").(model.User)\nif len(user.Roles) == 0 {\n    c.JSON(http.StatusForbidden, gin.H{\"error\": \"Access denied\"})\n    return\n}\n```\n\nIt then lists nodes, pods, namespaces, and services for the selected cluster at `pkg/system/handler.go:63-137` and returns aggregate data at `pkg/system/handler.go:147-169`.\n\nThe intended cluster boundary exists elsewhere. `pkg/cluster/cluster_handler.go:19-47` filters `/api/v1/clusters` with `rbac.CanAccessCluster(user, name)`, and `pkg/rbac/rbac.go:32-40` implements that cluster check. The vulnerable overview path skips the same check.\n\n## Reproduction\n\n1. Configure Kite with at least two clusters, for example `dev-cluster` and `prod-cluster`.\n2. Create a user with a role that allows only `dev-cluster` and does not match `prod-cluster`.\n3. Authenticate as that user.\n4. Send `GET /api/v1/overview` with header `x-cluster-name: prod-cluster`.\n5. Observe that the response includes aggregate inventory and capacity data for `prod-cluster` instead of returning 403.\n\nI also validated this locally with a Go proof test. The test constructs a fake `prod-cluster` containing one node, namespace, service, and pod. The user has a role limited to `dev-cluster` and `dev-ns` only. Before calling the handler, both controls return false:\n\n- `rbac.CanAccess(user, \"pods\", \"get\", \"prod-cluster\", \"_all\")`\n- `rbac.CanAccessCluster(user, \"prod-cluster\")`\n\nThe direct handler call then succeeds and returns the unauthorized production cluster aggregate data.\n\nCommand run:\n\n```bash\ncd /home/unkn0wn/security_audit/kite\ngo test ./pkg/system -run TestOverviewAllowsUserWithoutTargetClusterRBAC -v\n```\n\nKey output:\n\n```text\n=== RUN   TestOverviewAllowsUserWithoutTargetClusterRBAC\n    overview_rbac_poc_test.go:74: unauthorized overview response: {\"totalNodes\":1,\"readyNodes\":0,\"totalPods\":1,\"runningPods\":0,\"totalNamespaces\":1,\"totalServices\":1,\"prometheusEnabled\":false,\"resource\":{\"cpu\":{\"allocatable\":0,\"requested\":0,\"limited\":0},\"memory\":{\"allocatable\":0,\"requested\":0,\"limited\":0}}}\n--- PASS: TestOverviewAllowsUserWithoutTargetClusterRBAC (0.49s)\nPASS\nok  \tgithub.com/zxh326/kite/pkg/system\t0.711s\n```\n\n## Suggested remediation\n\nAdd an explicit cluster and resource authorization check before any overview data is queried. At minimum, reject users without `rbac.CanAccessCluster(user, cs.Name)`. A stricter fix should require the same resource permissions used by the AI `get_cluster_overview` tool:\n\n- `get nodes` at cluster scope\n- `get pods` across all namespaces\n- `get namespaces` at cluster scope\n- `get services` across all namespaces\n\nAlso consider moving every route that lacks its own complete authorization below `api.Use(middleware.RBACMiddleware())`, or adding per-handler authorization tests for all pre-RBAC routes.","state":0,"publishedAt":"2026-07-07T23:40:35+00:00","modifiedAt":"2026-07-21T19:19:24.1907696+00:00","affected":[{"ecosystem":"Go","name":"github.com/zxh326/kite","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.12.3"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/kite-org/kite/security/advisories/GHSA-gvhc-wv3v-7pf8","https://github.com/kite-org/kite"],"sourceUrl":"https://github.com/advisories/GHSA-gvhc-wv3v-7pf8","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-gvhc-wv3v-7pf8","identifiers":["GHSA-gvhc-wv3v-7pf8","CVE-2026-53487","GO-2026-5941"]},"retained":false,"historicalAffected":[]},{"revision":"9dcb5cc2d0e9496c88ed65016952b01b","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5941","aliases":["CVE-2026-53487","GHSA-gvhc-wv3v-7pf8"],"title":"Kite has an authenticated cluster RBAC bypass in /api/v1/overview in github.com/zxh326/kite","description":"Kite has an authenticated cluster RBAC bypass in /api/v1/overview in github.com/zxh326/kite","state":0,"publishedAt":"2026-07-17T19:42:05+00:00","modifiedAt":"2026-07-21T19:15:29.1974042+00:00","affected":[{"ecosystem":"Go","name":"github.com/zxh326/kite","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.12.3"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/kite-org/kite/security/advisories/GHSA-gvhc-wv3v-7pf8"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5941","license":"OSV · upstream source license applies","key":"osv:GO-2026-5941","identifiers":["GO-2026-5941","CVE-2026-53487","GHSA-gvhc-wv3v-7pf8"]},"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-10T10:21:23.1769119+00:00","complete":true,"records":1773,"lastAttemptAt":"2026-11-10T10:21:23.1769119+00:00","lastSuccessAt":"2026-11-10T10:21:23.4268898+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:23.4268987+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-8859cf40d4337e24bd2f258cc7778fbad01bb24c79d057aaf34cf1dfc6f8917d-8bdcdeeb414e06ff50ed637d818ac25d52680d19f71fc0ebe3f4c4b3f836ed38","complete":true,"records":421927,"lastAttemptAt":"2026-11-10T10:21:22.8157744+00:00","lastSuccessAt":"2026-11-10T09:21:38.1064889+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:22.8157744+00:00","snapshotPublishedAt":"2026-11-10T09:20:43+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-2e6a476534094233b48f2f0b6da5cf35","complete":true,"records":13689,"lastAttemptAt":"2026-11-10T10:21:50.2500014+00:00","lastSuccessAt":"2026-11-10T06:05:35.03+00:00","error":null,"lastVerifiedAt":"2026-11-10T06:05:35.03+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13742,"expectedIdentifiers":13742,"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-10T10:21:23.1769119+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-10T10:21:23.1769119+00:00","lastSuccessAt":"2026-11-10T10:21:23.4276529+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:23.4276532+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-b0b0499af228434598651aa5d221386e","complete":false,"records":13695,"lastAttemptAt":"2026-11-10T10:21:49.6403901+00:00","lastSuccessAt":"2026-11-10T10:21:49.637+00:00","error":"100 identifier lookups failed; latest failures include request timeout. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-10T10:21:49.637+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13642,"expectedIdentifiers":13742,"failedIdentifiers":100},{"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-cdffb4589856378aa42e8d1bd4a6c74e27a180d8160bf764c44715ef760f0a62","complete":true,"records":9932,"lastAttemptAt":"2026-11-10T10:21:23.1241572+00:00","lastSuccessAt":"2026-11-10T00:04:19.8260565+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:23.1241572+00:00","snapshotPublishedAt":"2026-11-09T23:48:01+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-26503967ae4379db8f374089589d6e03fb15bd31f820c9e992aaf93840c2236c","complete":true,"records":1971,"lastAttemptAt":"2026-11-10T10:21:22.8858542+00:00","lastSuccessAt":"2026-11-09T21:02:20.472473+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:22.8858542+00:00","snapshotPublishedAt":"2026-11-09T20:18:18+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-94169eec81ea3989aa551092397ff34ae53c104b4a6ce646e1524452e4ab2a39","complete":true,"records":3065,"lastAttemptAt":"2026-11-10T10:21:23.1397622+00:00","lastSuccessAt":"2026-11-10T08:04:45.5923716+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:23.1397622+00:00","snapshotPublishedAt":"2026-11-10T06:48:01+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-4331051b0b2d4ccdbdca3aa196b0be3818a465064a4b18dde4cf39c2250eb490","complete":true,"records":231599,"lastAttemptAt":"2026-11-10T10:21:23.0142877+00:00","lastSuccessAt":"2026-11-10T08:04:37.1757322+00:00","error":null,"lastVerifiedAt":"2026-11-10T10:21:23.0142877+00:00","snapshotPublishedAt":"2026-11-10T07:33:02+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}