| name | hardcoded-secrets-anti-pattern |
| description | Security anti-pattern for hardcoded credentials and secrets (CWE-798). Use when generating or reviewing code that handles API keys, passwords, database credentials, encryption keys, or any sensitive configuration. Detects embedded secrets and recommends environment variables or secret managers. |
Hardcoded Secrets Anti-Pattern
Severity: Critical
Summary
Hardcoded secrets embed sensitive credentials (API keys, passwords, database credentials) directly in source code. Anyone with code access—developers, version control history, or attackers—can extract these secrets. AI models frequently generate hardcoded secrets, trained on public code with this common bad practice. Secrets committed to public repositories are discovered and exploited by automated bots within minutes.
The Anti-Pattern
Never store secrets, credentials, or sensitive configuration values in files tracked by version control.
BAD Code Example
import requests
import psycopg2
API_KEY = "sk-live-123abc456def789ghi"
def get_weather(city):
url = f"https://api.weatherprovider.com/v1/current?city={city}"
headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.get(url, headers=headers)
return response.json()
DB_HOST = "localhost"
DB_USER = "admin"
DB_PASSWORD = "my_super_secret_password_123"
DB_NAME = "main_db"
def get_db_connection():
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASSWORD
)
return conn
GOOD Code Example
import os
import requests
import psycopg2
API_KEY = os.environ.get("WEATHER_API_KEY")
def get_weather(city):
if not API_KEY:
raise ValueError("WEATHER_API_KEY environment variable not set.")
url = f"https://api.weatherprovider.com/v1/current?city={city}"
headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.get(url, headers=headers)
return response.json()
DB_HOST = os.environ.get("DB_HOST", "localhost")
DB_USER = os.environ.get("DB_USER")
DB_PASSWORD = os.environ.get("DB_PASSWORD")
DB_NAME = os.environ.get("DB_NAME")
def get_db_connection():
if not all([DB_USER, DB_PASSWORD, DB_NAME]):
raise ValueError("Database environment variables are not fully configured.")
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASSWORD
)
return conn
Language-Specific Examples
JavaScript/Node.js:
const stripe = require('stripe')('sk_live_abc123def456ghi789');
const dbConfig = {
host: 'localhost',
user: 'admin',
password: 'MyP@ssw0rd123',
database: 'production_db'
};
require('dotenv').config();
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const dbConfig = {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
};
if (!process.env.STRIPE_SECRET_KEY || !process.env.DB_PASSWORD) {
throw new Error('Required environment variables not set');
}
Java/Spring Boot:
@Configuration
public class SecretsConfig {
@Bean
public AWSSecretsManager secretsManager() {
return AWSSecretsManagerClientBuilder.standard()
.withRegion("us-west-2")
.build();
}
@Bean
public String dbPassword(AWSSecretsManager secretsManager) {
GetSecretValueRequest request = new GetSecretValueRequest()
.withSecretId("prod/db/password");
GetSecretValueResult result = secretsManager.getSecretValue(request);
return result.getSecretString();
}
}
C# (ASP.NET Core):
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("Default")));
services.AddSingleton<IEmailService>(sp =>
new SendGridEmailService(Configuration["ApiKeys:SendGrid"]));
}
}
Detection
- Use secret scanning tools: Scan repository history automatically:
gitleaks detect --source . --verbose
trufflehog git file://. --only-verified
git-secrets --scan (pre-commit hook integration)
- Search for keywords: Grep for common patterns:
rg -i '(password|secret|api_?key|token|credential)\s*=\s*["\']'
rg 'sk-[a-zA-Z0-9]{32,}' (OpenAI API keys)
- Detect high-entropy strings: Identify random 32+ character strings:
trufflehog --entropy=True
detect-secrets scan --baseline .secrets.baseline
- Check configuration files: Audit committed configs:
git log --all --full-history -- "*.env" "config.json" "settings.py"
- Review files that should be in .gitignore
Prevention
Related Security Patterns & Anti-Patterns
References