Where
-Infinity
0
Severity
7.6
SSRF
AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:L/A:N

Summary

The koku-metrics-operator CostManagementMetricsConfig CRD exposes spec.prometheusconfig.serviceaddress as a free-form string with no host validation. The operator reads its own Kubernetes service-account token from /var/run/secrets/kubernetes.io/serviceaccount/token and configures it as the BearerToken for PromQL queries sent to this user-supplied address. The service-account token carries the manager-role ClusterRole, which grants get on all Secrets cluster-wide.

Impact

A principal with create/update permission on costmanagementmetricsconfigs in the operator namespace can harvest the operator's Kubernetes service-account token by redirecting Prometheus queries to an attacker-controlled endpoint. This token grants read access to every named Secret in any namespace across the cluster.

Affected Code

- api/v1beta1/metricsconfigtypes.go:198 — serviceaddress field definition (no validation) - internal/collector/prometheus.go:95-117 — token read and client configuration - config/rbac/role.yaml:18-22 — ClusterRole grants secrets:get cluster-wide

Remediation

Restrict serviceaddress to in-cluster Prometheus/Thanos endpoints via CRD CEL validation:

yaml x-kubernetes-validations: - rule: "url(self.serviceaddress).getHostname().endsWith('.openshift-monitoring.svc') || url(self.serviceaddress).getHostname().endsWith('.openshift-monitoring.svc.cluster.local')" message: "serviceaddress must target the in-cluster monitoring service"

Or use a TokenRequest API call with audience bound to prometheus-k8s so the token is not replayable against kube-apiserver.

1 / 2
Source: Red Hat
First published (updated )
Severity
7

Summary

The koku-metrics-operator CostManagementMetricsConfig CRD exposes spec.prometheusconfig.serviceaddress as a free-form string with no host validation. The operator reads its own Kubernetes service-account token from /var/run/secrets/kubernetes.io/serviceaccount/token and configures it as the BearerToken for PromQL queries sent to this user-supplied address. The service-account token carries the manager-role ClusterRole, which grants get on all Secrets cluster-wide.

Impact

A principal with create/update permission on costmanagementmetricsconfigs in the operator namespace can harvest the operator's Kubernetes service-account token by redirecting Prometheus queries to an attacker-controlled endpoint. This token grants read access to every named Secret in any namespace across the cluster.

Affected Code

- api/v1beta1/metricsconfigtypes.go:198 — serviceaddress field definition (no validation) - internal/collector/prometheus.go:95-117 — token read and client configuration - config/rbac/role.yaml:18-22 — ClusterRole grants secrets:get cluster-wide

Remediation

Restrict serviceaddress to in-cluster Prometheus/Thanos endpoints via CRD CEL validation:

yaml x-kubernetes-validations: - rule: "url(self.serviceaddress).getHostname().endsWith('.openshift-monitoring.svc') || url(self.serviceaddress).getHostname().endsWith('.openshift-monitoring.svc.cluster.local')" message: "serviceaddress must target the in-cluster monitoring service"

Or use a TokenRequest API call with audience bound to prometheus-k8s so the token is not replayable against kube-apiserver.

First published (updated )
Severity
7

Summary

The koku-metrics-operator CostManagementMetricsConfig CRD exposes spec.apiurl as a free-form string with no host allow-list or schema validation. When spec.authentication.type == token (the default), the operator reads the cluster-global openshift-config/pull-secret, extracts the cloud.openshift.com bearer token, and attaches it as Authorization: Bearer <token> on an outbound POST to the user-supplied URL. No comparison against the default https://console.redhat.com gates credential attachment.

Impact

A principal with create/update permission on costmanagementmetricsconfigs in the operator namespace can cause the operator to send the cluster's Red Hat Cloud / registry pull-secret bearer token to an arbitrary external or in-cluster endpoint. This credential authenticates the entire cluster to console.redhat.com and registry.redhat.io.

Affected Code

- api/v1beta1/metricsconfigtypes.go:249 — APIURL field definition (no validation) - internal/controller/costmanagementmetricsconfigcontroller.go:128,235,258,590 — credential extraction and URL construction - internal/crhchttp/httpclouddotredhat.go:94 — bearer token attachment to HTTP request

Remediation

Reject token authentication when apiurl != DefaultAPIURL. Add a CEL validation rule on the CRD:

yaml x-kubernetes-validations: - rule: "self.authentication.type != 'token' || self.apiurl == 'https://console.redhat.com'" message: "token authentication is only permitted against https://console.redhat.com"

Or implement the check in the reconciler before calling Upload().

First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203