- Advisory: GHSA-h9p5-fp5h-qpqr · CVE-2026-93538
- Severity: High (CVSS 4.0 7.1 —
AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N) · CWE-290 / CWE-639 / CWE-863 - Affected: Fleet
>=v0.12.0 <v0.12.19,>=v0.13.0 <v0.13.15,>=v0.14.0 <v0.14.10,>=v0.15.0 <v0.15.6,>=v0.16.0 <v0.16.1 - Patched: Fleet v0.16.1, v0.15.6, v0.14.10, v0.13.15, v0.12.19 · Rancher v2.15.1, v2.14.5, v2.13.9, v2.12.13, v2.11.17
- Status: publicly disclosed and fixed. Reported by Pig-Tail through coordinated disclosure.
During agent-initiated cluster registration the registering agent fully controls
ClusterRegistration.Spec.ClusterLabels, and the controller copied every key verbatim onto the
upstream Cluster object with no key allowlist:
// internal/cmd/controller/agentmanagement/controllers/clusterregistration/controller.go
if !config.Get().IgnoreClusterRegistrationLabels {
maps.Copy(labels, request.Spec.ClusterLabels) // arbitrary keys, incl. management.cattle.io/*
}Fleet resolves GitRepo and Bundle targets from exactly those labels, so a party able to register
a cluster into a shared workspace namespace can make its own cluster satisfy targeting rules an
administrator wrote for someone else's cluster.
clusterSelector / clusterGroupSelector matching on attacker-set label values would be a
hardening issue on its own. What makes this an authorization gap is that clusterName targeting
is spoofable as well: the name criterion falls back to the value of the
management.cattle.io/cluster-display-name label, which is copied straight from the agent-supplied
ClusterLabels. An agent that registers with
management.cattle.io/cluster-display-name: "victim-prod-cluster"satisfies a target the administrator believes selects one specific cluster by name — a reserved, management-plane-owned key being self-asserted by the registering party.
- Learn or guess the victim target selector — low-entropy operational labels (
env: prod) or the victim cluster display name, which is visible in the Rancher UI. - Register a cluster into the shared workspace namespace with crafted
ClusterLabels. - On the next Bundle/GitRepo reconcile the attacker's cluster matches the victim's target.
- Fleet creates the
BundleDeploymentand the resolved options/values Secret in the matched cluster's ownstatus.namespace, where the attacker's agent is entitled to read them.
Cross-tenant disclosure of another tenant's bundle manifests and of resolved Helm values, including
values sourced through valuesFrom Secrets, plus deployment of that tenant's intended workload onto
a cluster they do not control. The victim's own deployment is not modified or removed.
- The deployment must use agent-initiated registration — Fleet copies agent-supplied labels only
when it creates the
Clusterobject as part of that flow. - Standalone Rancher in its default configuration is not affected: Rancher uses
manager-initiated registration and creates the Fleet
Clusterobject in advance. - Multiple trust domains must share one Fleet registration namespace (several tenants registering
into
fleet-default), with the affected Bundle/GitRepo targeting by label or by cluster name. IgnoreClusterRegistrationLabelsleft at its defaultfalse.
- "Cluster labels are documented as agent-controlled, and
IgnoreClusterRegistrationLabelsexists." — True for ordinary labels. The reportable gap is the reservedmanagement.cattle.io/namespace being self-assertable, which defeats name-based targeting that administrators reasonably assume is not agent-controlled. - "Same namespace means same tenant." — Only under one-workspace-per-tenant. The multi-tenant deployments in scope share a registration namespace, which is why the finding is conditional.
- Not a duplicate of GHSA-xr65 (controller-side
valuesFromreads) or GHSA-864g (PSS bypass viaaddLabelsFromOptions): here the attacker abuses cluster labels to attract targeting and receives the deployment in its own namespace.
Fleet now discards reserved label keys supplied by an agent during agent-initiated registration, so
labels in the management.cattle.io/ namespace — including the cluster display name label used for
name-based targeting — can no longer be self-asserted. Such labels are honoured only when set by the
management plane after registration. Environments that intentionally relied on an agent setting a
reserved label at install time must apply it to the Cluster object from the management plane
instead.
Write-up only. No standalone runnable PoC is published for this finding here: confirming it end to end requires a two-cluster registration setup. The chain is verifiable statically at the cited call sites. Refer to the linked advisory for the vendor's own account and fixed releases.