CWE-798: Use of hardcoded credentials

Ensure that unique keys or secrets can be replaced or rejected at runtime and never hard-code sensitive information, such as passwords, and encryption keys in a component.

User accounts are either for human or machine type of users. Machine users, such as a front end connecting to a backend SQL, have it easy to use complexity during identity verification. Hardcoded credentials for machine users are typically caused by a missing strategy or architecture infrastructure to establish trust between components at deployment time. Human users need a level of usability for their identity verification such as a combination of what they have and what they can remember. A human user Identity Management (IDM) system needs to support initial access and users forgetting passphrases or passwords without jeopardizing security.

Examples of hard-coded sensitive information:

Storing sensitive data as part of a components source code or deliverable package can result in legal consequences governed by:

Issues with hard-coded sensitive information include:

Non-Compliant Code Example

The noncompliant01.py code example is simulating a front-end, back-end, and its deployment in one file. A real world example would have each run and delivered separately. The TestSimulateDeployingFrontEnd unit-test simulates a deployment of the front_end. The implementation of the front_end did not consider leaving connection details to the deployment and hardcoded them instead.

noncompliant01.py

# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""Non-compliant Code Example"""

import logging
import unittest

logging.basicConfig(encoding="utf-8", level=logging.DEBUG)


def front_end():
    """Dummy method demonstrating noncompliant implementation"""
    # A noncompliant implementation would typically hardcode server_config
    # and load it from a project global python file or variable
    server_config = {}
    server_config["IP"] = "192.168.0.1"
    server_config["PORT"] = "8080"
    server_config["USER"] = "admin"
    server_config["PASS"] = "SuperSecret123"

    # It would then use the configuration
    logging.debug("connecting to server IP %s", server_config["IP"])
    logging.debug("connecting to server PORT %s", server_config["PORT"])
    logging.debug("connecting to server USER %s", server_config["USER"])
    logging.debug("connecting to server PASS %s", server_config["PASS"])


class TestSimulateDeployingFrontEnd(unittest.TestCase):
    """
    Simulate the deployment starting the front_end to connect
    to the backend
    """

    def test_front_end(self):
        """Verifiy front_end implementation"""
        front_end()


if __name__ == "__main__":
    unittest.main()

The noncompliant01.py example will print the hardcoded connection information and credential information PASS SuperSecret123 in use.

Compliant Solution

Create reusable components by separating deployment such as connection information and trust between a deployed front-end and back-end.

   
Anti-pattern Recommended pattern
Passwords for machine to machine identity verification time limited keys or access tokens that are unique per deployment or instances and get assigned at deployment time.
Shared usernames RBAC, ABAC or policy engines
Hardcoded UIDs, GIDs identity names
Hardcoded IPs or ports Rather than hardcoding IP addresses DNS should be properly implemented in the deployment in combination with solutions such as:
- RFC 9250 - DNS over Dedicated QUIC Connections (ietf.org)
- RFC 7858 - Specification for DNS over Transport Layer Security (TLS) (ietf.org)
- RFC 6494 - Certificate Profile and Certificate Management for SEcure Neighbor Discovery (SEND) (ietf.org) for IPV6
- DNSSEC RFC 9364, RFC 6014, 5155, 4641….

The order and ways to resolve IPs is configured via /etc/nsswitch.conf on most Unix systems.

Using mTLS with a high granularity of machine identities can reduce or remove DNS related risks.

The compliant01.py code is using a config.ini file to decouple connection information. The deployment represented by TestSimulateDeployingFrontEnd is now in full control of proving connectivity information to the front-end and back-end. Using configuration files, such as ini, yaml or json, allows a language independent solution (bash vs python). The deployment, represented by TestSimulateDeployingFrontEnd, steering these files also secures them by making them read only to a single user via self.config_file_path.chmod(0o400). The password based identity verfication is replaced with a certificate based solution.

compliant01.py:

# SPDX-FileCopyrightText: OpenSSF project contributors
# SPDX-License-Identifier: MIT
"""Compliant Code Example"""

import logging
from pathlib import Path
import unittest
import configparser

logging.basicConfig(encoding="utf-8", level=logging.DEBUG)


def front_end(config_file_path: Path):
    """Simulating front end implementation"""
    # A compliant solution loads connection information from a well-protected file
    _config = configparser.ConfigParser()
    _config.read(config_file_path)

    # It would then use the configuration
    logging.debug("Loading deployment config %s", config_file_path.absolute())
    logging.debug("connecting to server IP %s", _config["SERVER"]["IP"])
    logging.debug("connecting to server PORT %s", _config["SERVER"]["PORT"])
    logging.debug("connecting to server USER %s", _config["SERVER"]["USER"])
    logging.debug("connecting to server pem %s", _config["SERVER"]["CERT_FILE"])


class TestSimulateDeployingFrontEnd(unittest.TestCase):
    """
    Simulate the deployment starting the front_end to connect
    to the backend
    """

    def setUp(self):
        config = configparser.ConfigParser()
        config["SERVER"] = {
            "IP": "192.168.0.1",
            "PORT": "8080",
            "USER": "admin",
            "CERT_FILE": "example.pem",
        }

        config["LOGGING"] = {
            "level": "DEBUG",
        }
        self.config_file_path = Path("config.ini", exist_ok=True)
        with open(self.config_file_path, "w", encoding="utf-8") as config_file:
            config.write(config_file)
        self.config_file_path.chmod(0o400)

    def test_front_end(self):
        """Verify front_end implementation"""
        front_end(self.config_file_path)

    def tearDown(self):
        """Clean up after us and remove the config file"""
        self.config_file_path.unlink()


if __name__ == "__main__":
    unittest.main()

The compliant01.py code avoids using password based authentication in the first place. It prints connection information only for convenience here and should not be considered in a real world implementation as per CWE-532: Insertion of Sensitive Information into Log File [OSSF 2025].

Automated Detection

Tool Version Checker Description
Bandit 1.7.4 on Python 3.10.4 B105
B106
B107
B105: hardcoded_password_string — Bandit documentation
B106: hardcoded_password_funcarg — Bandit documentation
B107: hardcoded_password_default — Bandit documentation
sonarsource   RSPEC-2068
RSPEC-6437
Python static code analysis: Hard-coded credentials are security-sensitive (sonarsource.com)
Credentials should not be hard-coded (sonarsource.com)
codeQL     Hard-coded credentials — CodeQL query help documentation (github.com)
   
MITRE CWE Pillar: CWE-693: Protection Mechanism Failure (4.12) (mitre.org)
MITRE CWE Base: CWE-798: Use of hardcoded credentials
MITRE CWE Variant: CWE-259: Use of hardcoded password
MITRE CWE Variant: CWE-321: Use of hardcode cryptographic key
SEI CERT Oracle Codign Standard for Java MSC03-J: Never hardcode sensitive information

Bibliography

   
[US Congress 1996] Health Insurance Portability and Accountability Act (HIPAA) [online].Available from: https://aspe.hhs.gov/reports/health-insurance-portability-accountability-act-1996 [accessed 27 Februrary 2025]
[European Parliament 2016] General Data Protection Regulation (GDPR) [online]. Available from: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=CIV&sectionNum=1798.150 [accessed 27 Februrary 2025]
[CPPA 2025] DIVISION 3. OBLIGATIONS [1427 - 3273.16] [online]. Available from: https://leginfo.legislature.ca.gov/faces/codes_displaySection.xhtml?lawCode=CIV&sectionNum=1798.150 [accessed 27 Februrary 2025]
[OSSF 2025] CWE-532: Insertion of Sensitive Information into Log File [online]. Available from: https://best.openssf.org/Secure-Coding-Guide-for-Python/CWE-664/CWE-532/ [accessed 27 Februrary 2025]