GHSA-wmj8-9953-vff5 OpenCost ServiceKey Endpoint Unauthorized Credential Overwrite/Injection
SummaryOpenCost contains an unauthenticated  file write vulnerability in the `/serviceKey` endpoint that allows remote attackers to overwrite the GCP service account key file without authentication. This can lead to service disruption, credential theft, and potential privilege escalation within Kubernetes clusters.Affected Versions**OpenCost**: All versions up to and including the latest release**Vulnerable File**: `pkg/costmodel/router.go` (lines 365-379)**Vulnerable Endpoint**: `POST /serviceKey`Vulnerability DetailsRoot CauseThe `AddServiceKey` function in `pkg/costmodel/router.go` accepts user-supplied data via POST request and writes it directly to a file without any authentication or input validation:**File Path Determination** (`core/pkg/env/core.go`):Security Issues**No Authentication**: Any network-accessible client can invoke the endpoint**No Input Validation**: User input is not validated as a valid GCP service account key**Overly Permissive CORS**: `Access-Control-Allow-Origin: *` allows cross-origin attacks**Predictable File Path**: File location controlled by `CONFIG_PATH` environment variableProof of ConceptEnvironment SetupPrerequisitesKubernetes cluster (tested on kind v1.30.0)Helm 3.xkubectl configuredStep 1: Create Namespace**Output**:Step 2: Add OpenCost Helm Repository**Output**:Step 3: Deploy OpenCost**Key Configuration**:`CONFIG_PATH=/tmp`: Sets writable directory for file operations**Output**:Step 4: Verify Deployment**Output**:Step 5: Verify Service Accessibility**Output**:ExploitationStep 6: Check Initial State**Output**:Note: File does not exist initiallyStep 7: Verify CONFIG_PATH Configuration**Output**:Note: CONFIG_PATH correctly set to /tmpStep 8: Execute Exploit**Request Details**:**Response Details**:Result: HTTP 200 OK - Request successful without authenticationStep 9: Verify File Write**Output**:Result: VULNERABILITY CONFIRMED - Malicious content successfully written to fileImpact AnalysisDirect Impact| Impact Type | Severity | Description |
|------------|----------|-------------|
| **Unauthorized Credential Overwrite** | High | Attacker can overwrite GCP service account key file content |
| **No Authentication Required** | High | Vulnerability can be exploited without any credentials |
| **CORS Misconfiguration** | Medium | Allows cross-origin attacks via malicious websites |
| **Fixed File Path** | Low | Attacker cannot control write location, only content |Attack Scenario AnalysisScenario 1: GCP Credential Overwrite Leading to Service Disruption**Attack Steps**:Attacker sends POST request with invalid JSON or malformed GCP key`/serviceKey` endpoint accepts request and overwrites existing `key.json` fileOpenCost attempts to access GCP API with corrupted credentialsGCP integration fails, cost data collection stops**Technical Details**:**Impact**:**Cost Monitoring Disruption**: Unable to retrieve GCP cloud cost data**Operational Impact**: FinOps processes dependent on cost data are blocked**Availability Degradation**: Manual intervention required to restore correct credentials**CVSS Impact Score**: Availability impact is Low (A:L)Scenario 2: Malicious Credential Injection for Data Hijacking**Attack Steps**:Attacker creates their own GCP project and service accountInjects attacker-controlled valid GCP credentials into OpenCostOpenCost uses attacker's credentials to send requests to GCP Billing APITarget organization's cost data is sent to attacker's GCP project**Technical Details**:**Impact**:**Sensitive Data Leakage**: Organization's cloud resource usage patterns and cost details**Business Intelligence Leakage**: Can infer business scale, growth trends, technology stack**Compliance Risk**: Cost data may contain protected business information**Data Leakage Examples**:Kubernetes cluster size and node configurationResource consumption per namespace (can map to business units)Cloud service usage patterns (databases, storage, compute instance types)Cost trends (can infer business growth or contraction)**CVSS Impact Score**: Confidentiality impact is None (C:N), but business impact is HighScenario 3: Cross-Origin Attack (CORS Exploitation)**Attack Steps**:User visits attacker-controlled malicious websiteMalicious JavaScript sends POST request to `http://localhost:9003/serviceKey`Due to CORS set to `*`, browser allows cross-origin requestUser's browser acts as proxy to execute credential overwrite attack**Prerequisites**:User exposes OpenCost service via `kubectl port-forward` or other meansUser's browser can access OpenCost endpoint**Technical Details**:**Impact**:**User-Unaware Attack**: No active user interaction required**Difficult to Trace**: Attack originates from victim's IP address**Limited Exploitation Conditions**: Requires OpenCost exposed to user-accessible networkVulnerability Limitations**What Attacker Cannot Control**:**File Write Path**: Fixed by `CONFIG_PATH` environment variable, attacker cannot modify**File Name**: Fixed as `key.json`, cannot write to other files**File Permissions**: Write permission is `0644`, attacker cannot escalate**Actual Attack Capabilities**:**File Content Control**: Complete control over `key.json` content**Unauthenticated Exploitation**: No credentials required to trigger**Remote Accessibility**: Can be exploited over network (if service exposed)Real-World Impact Assessment| Deployment Scenario | Risk Level | Description |
|---------------------|-----------|-------------|
| **Cluster-Internal Only** | Medium | Requires attacker to have cluster network access |
| **Exposed via Ingress** | High | Any internet user can exploit |
| **Exposed via NodePort** | High | Attackers with node network access can exploit |
| **Via port-forward** | Medium-High | Local dev environments vulnerable to CORS attacks |**Recommended Risk Rating**:Default deployment (cluster-internal): **Medium**Improperly exposed (public internet): **High**RemediationImmediate Actions (P0)1. Add Authentication2. Implement Input Validation3. Restrict CORSLong-term Solutions (P1)**Use Kubernetes Secrets**: Store credentials in Kubernetes Secrets instead of files**Implement RBAC**: Role-based access control for sensitive operations**Add Audit Logging**: Log all file write operations**Apply Least Privilege**: Minimize ClusterRole permissionsWorkaroundsUntil a patch is available, implement these mitigations:**Network Segmentation**: Restrict access to OpenCost service using NetworkPolicies**Disable Endpoint**: Remove or disable the `/serviceKey` endpoint if not required**Monitor File Changes**: Alert on modifications to `key.json` file**Use Read-only Filesystem**: Mount config directory as read-only where possibleReferences**Vulnerable Code**: `pkg/costmodel/router.go:365-379`**Environment Configuration**: `core/pkg/env/core.go`**OWASP**: [Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)**CWE-306**: [Missing Authentication for Critical Function](https://cwe.mitre.org/data/definitions/306.html)**CWE-20**: [Improper Input Validation](https://cwe.mitre.org/data/definitions/20.html)
CVSS v4.0 score: 8.8