skills/hardcoded-secrets-anti-pattern/SKILL.md
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.
npx skillsauth add igbuend/grimbard hardcoded-secrets-anti-patternInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Severity: Critical
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.
Never store secrets, credentials, or sensitive configuration values in files tracked by version control.
# VULNERABLE: Hardcoded API keys and database credentials in the source code.
import requests
import psycopg2
# 1. Hardcoded API Key
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()
# 2. Hardcoded Database Password
DB_HOST = "localhost"
DB_USER = "admin"
DB_PASSWORD = "my_super_secret_password_123" # Exposed in the code
DB_NAME = "main_db"
def get_db_connection():
# The password is right here for any attacker to see.
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASSWORD
)
return conn
# SECURE: Load secrets from the environment or a dedicated secrets manager.
import os
import requests
import psycopg2
# 1. API key loaded from an environment variable.
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()
# 2. Database credentials loaded from environment variables.
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():
# The application will fail safely if secrets are not configured in the environment.
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
JavaScript/Node.js:
// VULNERABLE: Hardcoded credentials
const stripe = require('stripe')('sk_live_abc123def456ghi789'); // Exposed!
const dbConfig = {
host: 'localhost',
user: 'admin',
password: 'MyP@ssw0rd123', // Never do this!
database: 'production_db'
};
// SECURE: Use environment variables
require('dotenv').config(); // Load .env file
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:
// VULNERABLE: Hardcoded in application.properties
// application.properties:
// spring.datasource.password=MySecretPassword123
// aws.access.key=AKIAIOSFODNN7EXAMPLE
// SECURE: Use environment variables or secret managers
// application.properties:
// spring.datasource.password=${DB_PASSWORD}
// aws.access.key=${AWS_ACCESS_KEY}
// Or use AWS Secrets Manager
@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):
// VULNERABLE: Hardcoded in appsettings.json
// {
// "ConnectionStrings": {
// "Default": "Server=localhost;Database=mydb;User=admin;Password=Secret123;"
// },
// "ApiKeys": {
// "SendGrid": "SG.abc123def456ghi789"
// }
// }
// SECURE: Use User Secrets for dev, Azure Key Vault for production
// Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Connection string from environment or User Secrets
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("Default")));
// API key from Azure Key Vault (production) or User Secrets (dev)
services.AddSingleton<IEmailService>(sp =>
new SendGridEmailService(Configuration["ApiKeys:SendGrid"]));
}
}
// Set secrets:
// dotnet user-secrets set "ConnectionStrings:Default" "Server=..."
// Or use Azure Key Vault in production
gitleaks detect --source . --verbosetrufflehog git file://. --only-verifiedgit-secrets --scan (pre-commit hook integration)rg -i '(password|secret|api_?key|token|credential)\s*=\s*["\']'rg 'sk-[a-zA-Z0-9]{32,}' (OpenAI API keys)trufflehog --entropy=Truedetect-secrets scan --baseline .secrets.baselinegit log --all --full-history -- "*.env" "config.json" "settings.py".env file (or similar) to your .gitignore to prevent accidental commits of local development secrets.development
Security anti-pattern for Cross-Site Scripting vulnerabilities (CWE-79). Use when generating or reviewing code that renders HTML, handles user input in web pages, uses innerHTML/document.write, or builds dynamic web content. Covers Reflected, Stored, and DOM-based XSS. AI code has 86% XSS failure rate.
development
Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries.
development
Security anti-pattern for weak password hashing (CWE-327, CWE-759). Use when generating or reviewing code that stores or verifies user passwords. Detects use of MD5, SHA1, SHA256 without salt, or missing password hashing entirely. Recommends bcrypt, Argon2, or scrypt.
development
Security anti-pattern for weak encryption (CWE-326, CWE-327). Use when generating or reviewing code that encrypts data, handles encryption keys, or uses cryptographic modes. Detects DES, ECB mode, static IVs, and custom crypto implementations.