insecure-defaults-anti-pattern
Insecure Defaults Anti-Pattern
Severity: Critical
Summary
Insecure defaults occur when applications continue operating with weak or default values when required configuration is missing. Unlike hardcoded secrets (which are always present), insecure defaults create fail-open conditions where missing environment variables cause the application to silently use unsafe fallback values. This is particularly dangerous because the vulnerability only manifests in misconfigured deployments.
The Anti-Pattern
Never provide fallback values for security-critical configuration. Applications should fail immediately (fail-secure) when required secrets or security settings are missing.
Key Distinction
| Pattern | Behavior | Risk |
|---|---|---|
| Fail-open (BAD) | Uses default when config missing | Silent security bypass |
| Fail-secure (GOOD) | Crashes when config missing | Deployment fails safely |
BAD Code Examples
# VULNERABLE: Fail-open - application runs with weak defaults
import os
import jwt
# 1. Default secret when environment variable is missing
SECRET_KEY = os.environ.get("SECRET_KEY", "default-secret-change-me")
# 2. Debug mode defaults to enabled
DEBUG = os.environ.get("DEBUG", "true").lower() == "true"
# 3. Weak algorithm fallback
JWT_ALGORITHM = os.environ.get("JWT_ALGORITHM", "HS256") # Should require RS256
def create_token(user_id):
# Runs with weak secret if SECRET_KEY not set
return jwt.encode({"user_id": user_id}, SECRET_KEY, algorithm=JWT_ALGORITHM)
def verify_token(token):
# Attacker can forge tokens using "default-secret-change-me"
return jwt.decode(token, SECRET_KEY, algorithms=[JWT_ALGORITHM])
// VULNERABLE: Node.js fail-open patterns
const express = require('express');
const session = require('express-session');
const app = express();
// 1. Session secret with insecure default
app.use(session({
secret: process.env.SESSION_SECRET || 'keyboard cat', // Fail-open!
resave: false,
saveUninitialized: true
}));
// 2. CORS defaults to permissive
const corsOrigin = process.env.CORS_ORIGIN || '*'; // Allows all origins!
// 3. Rate limiting disabled by default
const rateLimit = process.env.RATE_LIMIT || 0; // 0 = unlimited
GOOD Code Examples
# SECURE: Fail-secure - application crashes if config missing
import os
import sys
import jwt
def get_required_env(name):
"""Get required environment variable or exit."""
value = os.environ.get(name)
if not value:
sys.exit(f"FATAL: Required environment variable {name} is not set")
return value
# 1. No default - must be configured
SECRET_KEY = get_required_env("SECRET_KEY")
# 2. Debug defaults to disabled (safe default)
DEBUG = os.environ.get("DEBUG", "false").lower() == "true"
# 3. Validate algorithm is secure
JWT_ALGORITHM = os.environ.get("JWT_ALGORITHM", "RS256")
if JWT_ALGORITHM not in ["RS256", "RS384", "RS512", "ES256", "ES384", "ES512"]:
sys.exit(f"FATAL: Insecure JWT algorithm: {JWT_ALGORITHM}")
def create_token(user_id):
return jwt.encode({"user_id": user_id}, SECRET_KEY, algorithm=JWT_ALGORITHM)
// SECURE: Node.js fail-secure patterns
const express = require('express');
const session = require('express-session');
function requireEnv(name) {
const value = process.env[name];
if (!value) {
console.error(`FATAL: Required environment variable ${name} is not set`);
process.exit(1);
}
return value;
}
const app = express();
// 1. Session secret required - no default
app.use(session({
secret: requireEnv('SESSION_SECRET'),
resave: false,
saveUninitialized: false, // Also secure default
cookie: { secure: true } // Require HTTPS
}));
// 2. CORS must be explicitly configured
const corsOrigin = requireEnv('CORS_ORIGIN');
if (corsOrigin === '*') {
console.error('FATAL: CORS_ORIGIN cannot be wildcard in production');
process.exit(1);
}
// 3. Rate limiting with secure default
const rateLimit = parseInt(process.env.RATE_LIMIT || '100', 10);
Language-Specific Examples
Go:
// VULNERABLE: Fail-open defaults
func getConfig() Config {
return Config{
// Default secret if not set
JWTSecret: getEnvOrDefault("JWT_SECRET", "development-secret"),
// Debug enabled by default
Debug: getEnvOrDefault("DEBUG", "true") == "true",
// Permissive CORS
CORSOrigin: getEnvOrDefault("CORS_ORIGIN", "*"),
}
}
// SECURE: Fail-secure - panic on missing required config
func getConfig() Config {
jwtSecret := os.Getenv("JWT_SECRET")
if jwtSecret == "" {
log.Fatal("FATAL: JWT_SECRET environment variable required")
}
corsOrigin := os.Getenv("CORS_ORIGIN")
if corsOrigin == "" || corsOrigin == "*" {
log.Fatal("FATAL: CORS_ORIGIN must be explicitly set (not wildcard)")
}
return Config{
JWTSecret: jwtSecret,
Debug: os.Getenv("DEBUG") == "true", // Defaults to false
CORSOrigin: corsOrigin,
}
}
Java/Spring Boot:
// VULNERABLE: application.properties with insecure defaults
// jwt.secret=${JWT_SECRET:default-secret-do-not-use}
// cors.allowed-origins=${CORS_ORIGINS:*}
// debug.enabled=${DEBUG:true}
// SECURE: Require configuration, no insecure defaults
@Configuration
public class SecurityConfig {
@Value("${jwt.secret}") // No default - fails if missing
private String jwtSecret;
@Value("${cors.allowed-origins}") // No default
private String corsOrigins;
@PostConstruct
public void validateConfig() {
if (jwtSecret == null || jwtSecret.length() < 32) {
throw new IllegalStateException("jwt.secret must be at least 32 characters");
}
if ("*".equals(corsOrigins)) {
throw new IllegalStateException("cors.allowed-origins cannot be wildcard");
}
}
}
Detection
Search for fallback patterns in configuration code:
# Python: os.environ.get with default values for secrets
rg 'environ\.get\([^)]+,\s*["\'][^"\']+["\']' --type py
# JavaScript: process.env with || fallback
rg 'process\.env\.\w+\s*\|\|' --type js --type ts
# Go: getEnvOrDefault patterns
rg 'getEnv.*Default|Getenv.*""' --type go
# Generic: Common insecure default strings
rg -i '(secret|key|password|token).*default|change.?me|keyboard.?cat|development'
What to Ignore (Not Vulnerabilities)
- Test directories and spec files
- Example/sample/template files
- Development-only configurations (docker-compose.dev.yml)
- Documentation and README files
- Build-time placeholders replaced during deployment
- Fail-secure patterns that crash on missing config
Prevention
- Never provide defaults for secrets - API keys, passwords, signing keys must be explicitly configured
- Fail-secure on startup - Crash immediately if required configuration is missing
- Default security settings to restrictive - Debug=false, CORS=specific origins, rate limiting=enabled
- Validate configuration at startup - Check for weak values, not just missing values
- Use schema validation - Validate all config against expected types and constraints
- Separate dev/prod configs - Never share configuration between environments
Related Anti-Patterns
- Hardcoded Secrets: Secrets embedded in code vs. insecure fallback defaults
- Debug Mode in Production: Debug=true as insecure default
- Missing Authentication: Auth disabled by default
- Open CORS: CORS=* as insecure default
References
- CWE-1188: Initialization with Hard-Coded Network Resource Configuration Data
- CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag
- CWE-276: Incorrect Default Permissions
- CAPEC-121: Exploit Non-Production Interfaces
- OWASP Security Misconfiguration
- OWASP API Security API8:2023 - Security Misconfiguration
- OWASP Secrets Management Cheat Sheet
- Source: Modified from Trail of Bits Skills (CC BY-SA 4.0)
More from igbuend/grimbard
tikz
LaTeX TikZ/PGF package for programmatic vector graphics and diagrams. Use when helping users draw flowcharts, trees, graphs, automata, circuits, geometric figures, or any custom diagram in LaTeX.
94latex
Comprehensive LaTeX reference for document creation, formatting, mathematics, tables, figures, bibliographies, and compilation. Use when helping users write, edit, debug, or compile LaTeX documents.
38pgfplots
LaTeX pgfplots package for data visualization and plotting. Use when helping users create line plots, bar charts, scatter plots, histograms, 3D surfaces, or any scientific/data plot in LaTeX.
33biblatex
LaTeX biblatex/biber packages for modern bibliography management. Use when helping users cite references, manage .bib files, choose citation styles, or troubleshoot bibliography compilation.
24ethical-hacking-ethics
Legal and ethical guidelines for bug bounties, pentesting, and security research. Use when conducting authorized security testing.
12amsmath
LaTeX amsmath/amssymb/mathtools packages for mathematical typesetting. Use when helping users write equations, align math, use mathematical symbols, matrices, theorems, or any advanced math formatting.
12