Hardcoded secrets

Secrets embedded in application code

Description

Passwords, API keys, and authentication tokens embedded in application code may be exposed when the code is disclosed.

Potential impact

  • Secret exposure: An attacker may obtain secrets from the source code.
  • Account takeover: Exposed secrets may allow access to accounts.
  • API abuse: An attacker may misuse services with leaked API keys.

Remediation

  • Supply secrets through environment variables instead of embedding them in code.
  • Use a secret manager such as HashiCorp Vault or AWS Secrets Manager.
  • Review and audit code for embedded secrets.

Revoke exposed secrets and replace them with new values. Restrict access to environment variables too, and keep their values out of logs.

Examples

Django

Before

python
# Hardcoded Django secrets
SECRET_KEY = 'your-hardcoded-secret-key'
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

After

python
# Django secrets supplied through the environment
import os

SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
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: SECRET_KEY and the database password are embedded in the source.
  • After: Secrets come from the environment and are not stored in the source.

Flask

Before

python
# Hardcoded Flask secrets
class Config:
    SECRET_KEY = 'your-hardcoded-secret-key'
    SQLALCHEMY_DATABASE_URI = 'postgresql://myuser:mypassword@localhost/mydatabase'

After

python
# Flask secrets supplied through the environment
import os

class Config:
    SECRET_KEY = os.getenv('FLASK_SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL')

Explanation:

  • Before: SECRET_KEY and credentials in the database URI are embedded in the source.
  • After: Secrets come from the environment and are not stored in the source.

FastAPI

Before

python
# Hardcoded FastAPI session secret
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key='your-hardcoded-secret-key', https_only=True)

After

python
# FastAPI session secret supplied through the environment
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
import os

app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key=os.environ['FASTAPI_SECRET_KEY'], https_only=True)

Explanation:

  • Before: The session middleware's secret_key is embedded in the source.
  • After: The session secret comes from the environment instead.

References