Bug 2509249 (CVE-2026-18378)

Summary: CVE-2026-18378 project-koku/koku-metrics-operator: koku-metrics-operator: cluster pull-secret token exfiltration via user-controlled api_url (SSRF / confused deputy)
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: cmyers, dnakabaa, kaycoth, lcouzens
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in koku-metrics-operator. The operator's CostManagementMetricsConfig custom resource allows user able to edit the CR to specify an arbitrary upload URL. When authentication.type is set to token (the default), the cluster-global Red Hat Cloud pull-secret bearer token is attached to HTTP requests sent to this user-controlled URL, allowing the attacker to obtain the token.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2026-07-30 11:03:11 UTC
## Summary

The koku-metrics-operator CostManagementMetricsConfig CRD exposes `spec.api_url` 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/metricsconfig_types.go:249` — `APIURL` field definition (no validation)
- `internal/controller/costmanagementmetricsconfig_controller.go:128,235,258,590` — credential extraction and URL construction
- `internal/crhchttp/http_cloud_dot_redhat.go:94` — bearer token attachment to HTTP request

## Remediation

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

```yaml
x-kubernetes-validations:
- rule: "self.authentication.type != 'token' || self.api_url == '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()`.