Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Requires a valid authenticated session with any assigned role (PR:L); only aggregate cluster inventory counts exposed, not secrets or credentials (C:L).
Primary rating from Vendor (https://github.com/kite-org/kite).
CVSS VectorVendor: https://github.com/kite-org/kite
Lifecycle Timeline
1DescriptionCVE.org
Summary
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.
The issue is present on current main commit 38c9bb9d4b746c0d2a8252f3c35cdfa07ab01c21 and latest release v0.12.2 at commit 0aae35abb2d6a8adf623fe60349261aa48753ccc.
Impact
A 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.
The validated impact is confidentiality only. I did not prove Kubernetes mutation, pod names, secret values, kubeconfig contents, or bearer token exposure through this endpoint.
Technical details
routes.go registers /api/v1/overview before the global RBAC middleware is applied:
routes.go:131-133:/api/v1getsRequireAuth()andClusterMiddleware(cm).routes.go:135:/api/v1/overviewis registered.routes.go:171:api.Use(middleware.RBACMiddleware())is applied only after overview and several other routes are registered.
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.
pkg/system/handler.go:47-52 retrieves the selected cluster and user, but only rejects users with zero roles:
cs := c.MustGet("cluster").(*cluster.ClientSet)
user := c.MustGet("user").(model.User)
if len(user.Roles) == 0 {
c.JSON(http.StatusForbidden, gin.H{"error": "Access denied"})
return
}It 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.
The 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.
Reproduction
- Configure Kite with at least two clusters, for example
dev-clusterandprod-cluster. - Create a user with a role that allows only
dev-clusterand does not matchprod-cluster. - Authenticate as that user.
- Send
GET /api/v1/overviewwith headerx-cluster-name: prod-cluster. - Observe that the response includes aggregate inventory and capacity data for
prod-clusterinstead of returning 403.
I 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:
rbac.CanAccess(user, "pods", "get", "prod-cluster", "_all")rbac.CanAccessCluster(user, "prod-cluster")
The direct handler call then succeeds and returns the unauthorized production cluster aggregate data.
Command run:
cd /home/unkn0wn/security_audit/kite
go test ./pkg/system -run TestOverviewAllowsUserWithoutTargetClusterRBAC -vKey output:
=== RUN TestOverviewAllowsUserWithoutTargetClusterRBAC
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}}}
--- PASS: TestOverviewAllowsUserWithoutTargetClusterRBAC (0.49s)
PASS
ok github.com/zxh326/kite/pkg/system 0.711sSuggested remediation
Add 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:
get nodesat cluster scopeget podsacross all namespacesget namespacesat cluster scopeget servicesacross all namespaces
Also 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.
AnalysisAI
Cluster-level RBAC bypass in Kite (github.com/zxh326/kite) v0.12.2 allows any authenticated user to retrieve aggregate inventory and capacity data from Kubernetes clusters they are not authorized to access. By supplying an arbitrary cluster name in the x-cluster-name header, a low-privileged user scoped to one cluster can enumerate node counts, pod counts, namespace counts, service counts, and CPU/memory resource totals from other configured clusters. No public exploit identified at time of analysis, though the reporter provided and validated a working Go proof-of-concept test demonstrating the bypass.
Technical ContextAI
Kite is an open-source Kubernetes cluster management dashboard written in Go using the Gin web framework (pkg:go/github.com_zxh326_kite). The root cause is CWE-862 (Missing Authorization) arising from route registration order in routes.go: the /api/v1/overview route is registered at line 135 before the global middleware.RBACMiddleware() is applied at line 171. The ClusterMiddleware at pkg/middleware/cluster.go:21-40 accepts any cluster name from the x-cluster-name header, query parameter, or cookie and injects the matching ClientSet without verifying cluster-level permissions. The GetOverview handler at pkg/system/handler.go:47-52 only checks len(user.Roles) > 0, which is satisfied by any authenticated user regardless of which clusters their roles permit. In contrast, the /api/v1/clusters route correctly enforces rbac.CanAccessCluster(user, name) at pkg/cluster/cluster_handler.go:19-47, demonstrating that the authorization logic exists but was not applied to the overview endpoint.
RemediationAI
No vendor-released patch has been identified at time of analysis; a remediation version is not available from the provided data. The reporter's recommended fix is to add an explicit rbac.CanAccessCluster(user, cs.Name) authorization check at the start of the GetOverview handler in pkg/system/handler.go before any cluster data is queried, mirroring the check already in place at pkg/cluster/cluster_handler.go:19-47. A stricter fix should additionally enforce resource-level permissions (get nodes, get pods, get namespaces, get services). Structurally, moving all routes that lack complete per-handler authorization to be registered after api.Use(middleware.RBACMiddleware()) in routes.go would address the root cause and prevent similar bypasses on other pre-RBAC routes. As a compensating control until a patch is released, operators should restrict network access to the Kite API to trusted internal networks only and audit all user roles to minimize the number of accounts with any assigned role on multi-cluster deployments. Monitor https://github.com/kite-org/kite/security/advisories/GHSA-gvhc-wv3v-7pf8 for patch availability.
More in Kubernetes
View allA critical vulnerability in Kubernetes ingress-nginx controller allows unauthenticated attackers with pod network access
Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio
Kubernetes ingress-nginx contains a configuration injection vulnerability via the mirror-target and mirror-host Ingress
A security issue was discovered in ingress-nginx https://github.com/kubernetes/ingress-nginx where the `auth-url` Ingres
A security issue was discovered in ingress-nginx https://github.com/kubernetes/ingress-nginx where the `auth-tls-match-c
Kubernetes API server in all versions allow an attacker who is able to create a ClusterIP service and set the spec.exter
A security issue was discovered in Kubernetes where a user that can create pods on Windows nodes may be able to escalate
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Rated critical severity (CVSS 9.9), this vulne
Unauthenticated remote attackers can trigger complete database overwrites, server-side file reads, and SSRF attacks agai
The Kubernetes integration in GitLab Enterprise Edition 11.x before 11.2.8, 11.3.x before 11.3.9, and 11.4.x before 11.4
Fluentd configuration injection in the kube-logging Logging operator before 6.6.0 allows a namespace-scoped user who can
Kyverno Kubernetes policy engine prior to 1.x has a privilege escalation vulnerability (CVSS 9.9) allowing policy bypass
Same weakness CWE-862 – Missing Authorization
View allSame technique Authentication Bypass
View allVendor StatusVendor
SUSE
Severity: Moderate| Product | Status |
|---|---|
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP6 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-64181
GHSA-gvhc-wv3v-7pf8