Hardcoded credentials

Credentials embedded in source code

Description

Embedding credentials such as usernames, passwords, or API keys directly in source code exposes them if the code is disclosed.

Potential impact

  • Credential exposure: An attacker may use leaked credentials for unauthorized access.
  • Privilege abuse: Credentials with administrator privileges can allow an attacker to modify the system.
  • Data disclosure: Sensitive information may be exposed.

Remediation

  • Supply credentials through environment variables instead of embedding them in code.
  • Store and manage credentials in a protected secret store.
  • Rotate credentials as needed and revoke unused credentials.

Revoke exposed credentials and replace them with new values. In the examples, set DATABASE_URL to the complete connection string managed by your deployment environment.

Examples

Django

Before

python
# Hardcoded Django credentials
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

After

python
# Django credentials from the environment
import os

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'PORT': os.getenv('DB_PORT'),
    }
}

Explanation:

  • Before: Database credentials are embedded in the source and may be disclosed with it.
  • After: Credentials are supplied through the environment instead of the source.

Flask

Before

python
# Hardcoded Flask credentials
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://myuser:mypassword@localhost/mydatabase'

After

python
# Flask credentials from the environment
import os

app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']

Explanation:

  • Before: The database connection string embeds credentials.
  • After: The complete connection string comes from the environment.

FastAPI

Before

python
# Hardcoded FastAPI credentials
DATABASE_URL = "postgresql://myuser:mypassword@localhost/mydatabase"

@app.on_event("startup")
async def startup():
    app.state.pool = await asyncpg.create_pool(DATABASE_URL)

After

python
# FastAPI credentials from the environment
import os

DATABASE_URL = os.environ['DATABASE_URL']

@app.on_event("startup")
async def startup():
    app.state.pool = await asyncpg.create_pool(DATABASE_URL)

Explanation:

  • Before: The database connection string embeds credentials.
  • After: The complete connection string comes from the environment.

References