Skip to main content

Free 30-min security demo Book Now

Academy Key Management Failures
Intermediate · 20 min

Key Management Failures

Learn the dangers of hard-coded keys, keys in source control, and how to use secrets managers properly.

1 Hard-Coded Keys and Keys in Source Control

Cryptographic keys hard-coded in source code or committed to version control are one of the most common and easily exploitable security failures. Git history is permanent — even deleted files remain accessible.

Vulnerable patterns:

# Hard-coded in source (NEVER do this)
AES_KEY = b"mysupersecretkey16"
JWT_SECRET = "my-jwt-secret-key"
API_KEY = "sk_live_abcdef123456"
// In JavaScript config file
const config = {
  stripeKey: "sk_live_AbCdEfGhIjKlMnOp",  // Committed to public repo!
  dbPassword: "admin123"
};

Git history exposure:

# Key "deleted" in latest commit is still visible
git log --all --full-history -- secrets.py
git show abc123:secrets.py  # Key is still there!

Automated scanners (GitGuardian, truffleHog) continuously monitor public repositories and identify exposed secrets within seconds of a commit.

Key rotation absence: Even if a key is not in source control, never rotating keys means a single compromise is permanent. Keys should have defined lifetimes.

2 Secrets Managers and Environment Variables

Store secrets in environment variables at minimum, and use dedicated secrets managers for production systems.

Environment variables (minimum viable):

import os

AES_KEY = os.environ["AES_KEY"].encode()  # Fail loudly if not set
JWT_SECRET = os.environ["JWT_SECRET"]

# With a .env file locally (never commit .env!)
# .gitignore should include: .env, .env.local, *.key, *.pem

AWS Secrets Manager:

import boto3
import json

def get_secret(secret_name):
    client = boto3.client("secretsmanager", region_name="us-east-1")
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response["SecretString"])

secrets = get_secret("prod/myapp/database")
DB_PASSWORD = secrets["password"]

Defense checklist:

  • Never hard-code keys, passwords, or tokens in source code
  • Add .env and *.key to .gitignore
  • Use environment variables for development
  • Use a secrets manager (Vault, AWS Secrets Manager, Azure Key Vault) for production
  • Rotate keys regularly and immediately after any suspected exposure
  • Scan git history with truffleHog or git-secrets before open-sourcing

Knowledge Check

0/3 correct
Q1

A developer removes an API key from source code and pushes a new commit. Is the key still exposed?

Q2

What is the advantage of a secrets manager over environment variables?

Q3

What should you do immediately upon discovering a secret was committed to a public repository?

Code Exercise

Move Secrets to Environment Variables

The application has hard-coded cryptographic keys. Move them to environment variables with proper error handling if they are not set.

python

Put it into practice

Find Key Management Failures in your own code

Offensive360 SAST traces the tainted data flow behind this class of bug across 60+ languages and ships a secure fix with every finding. Public open-source projects scan free; teams can see it on their own repository in a 30-minute demo.