skills/debug-mode-production-anti-pattern/SKILL.md
Security anti-pattern for debug mode in production (CWE-215). Use when generating or reviewing code that configures application settings, deployment configurations, or error handling. Detects hardcoded debug flags and development-only features in production.
npx skillsauth add igbuend/grimbard debug-mode-production-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: High
Debug mode in production exposes sensitive system information and creates backdoors. Occurs when development settings remain enabled in deployment. Common in AI-generated code that hardcodes debug flags or fails to differentiate environments.
This anti-pattern manifests in two primary ways:
DEBUG = True never changes, so the application runs in debug mode in all environments./debug/env, /_debug/sql) included in production builds provide attack vectors.# VULNERABLE: Hardcoded debug flag and unprotected debug routes
import os
from flask import Flask, jsonify
app = Flask(__name__)
app.config['DEBUG'] = True # Hardcoded debug mode
@app.route("/")
def index():
return "Welcome!"
# This debug route exposes all environment variables, including potential secrets.
# It should never be present in a production environment.
@app.route("/debug/env")
def debug_env():
if app.config['DEBUG']:
return jsonify(os.environ.copy())
return "Not in debug mode."
if __name__ == "__main__":
app.run()
# SECURE: Environment-based configuration and conditional routes
import os
from flask import Flask, jsonify
app = Flask(__name__)
# Load configuration from the environment. Default to 'production'.
APP_ENV = os.environ.get('APP_ENV', 'production')
app.config['DEBUG'] = APP_ENV == 'development'
@app.route("/")
def index():
return "Welcome!"
# This debug route is now conditionally registered and will only exist
# if the application is explicitly run in a development environment.
if app.config['DEBUG']:
@app.route("/debug/env")
def debug_env():
return jsonify(os.environ.copy())
# It's also a good practice to add a startup check to prevent accidental
# deployment of debug mode to production.
if APP_ENV == 'production' and app.config['DEBUG']:
raise ValueError("FATAL: Debug mode is enabled in a production environment. Aborting.")
if __name__ == "__main__":
app.run()
BAD:
// VULNERABLE: Hardcoded debug flag in Express
const express = require('express');
const app = express();
// Hardcoded debug mode
const DEBUG = true;
app.get('/', (req, res) => {
res.send('Welcome!');
});
// Debug route exposes environment variables
app.get('/debug/env', (req, res) => {
if (DEBUG) {
res.json(process.env);
} else {
res.send('Not in debug mode.');
}
});
app.listen(3000);
GOOD:
// SECURE: Environment-based configuration
const express = require('express');
const app = express();
// Load from environment, default to production
const APP_ENV = process.env.APP_ENV || 'production';
const DEBUG = APP_ENV === 'development';
app.get('/', (req, res) => {
res.send('Welcome!');
});
// Conditionally register debug route
if (DEBUG) {
app.get('/debug/env', (req, res) => {
res.json(process.env);
});
}
// Startup check prevents production debug mode
if (APP_ENV === 'production' && DEBUG) {
throw new Error('FATAL: Debug mode enabled in production. Aborting.');
}
app.listen(3000);
BAD:
// VULNERABLE: Hardcoded debug in application.properties
// application.properties:
// debug=true
// logging.level.root=DEBUG
@RestController
public class DebugController {
@Value("${debug}")
private boolean debug;
@GetMapping("/debug/env")
public Map<String, String> debugEnv() {
if (debug) {
return System.getenv();
}
return Map.of("error", "Not in debug mode");
}
}
GOOD:
// SECURE: Profile-based configuration
// application-dev.properties:
// debug=true
// application-prod.properties:
// debug=false
@RestController
@Profile("dev") // Only register in development profile
public class DebugController {
@GetMapping("/debug/env")
public Map<String, String> debugEnv() {
return System.getenv();
}
}
// Application startup check
@Component
public class EnvironmentValidator implements ApplicationRunner {
@Value("${spring.profiles.active:prod}")
private String activeProfile;
@Value("${debug:false}")
private boolean debug;
@Override
public void run(ApplicationArguments args) {
if ("prod".equals(activeProfile) && debug) {
throw new IllegalStateException(
"FATAL: Debug mode enabled in production. Aborting."
);
}
}
}
Python/Flask/Django:
DEBUG = True in source codedebug=True in Flask configDEBUG = True in Django settings.py@app.route("/debug/JavaScript/Node.js/Express:
const DEBUG = true in source codeprocess.env.NODE_ENV !== 'production' checks missingapp.get('/debug/Java/Spring Boot:
debug=true in application.propertieslogging.level.root=DEBUG in production@Profile("dev")spring.devtools.restart.enabled=true in prodPHP:
error_reporting(E_ALL) in productiondisplay_errors = On in php.iniAPP_DEBUG=true in .envConfiguration Files:
.env files with DEBUG=truedebug: true"debug": trueSearch Patterns:
DEBUG.*=.*[Tt]rue|debug.*:.*true|\/debug\/|process\.env\.NODE_ENVDEBUG = True.Manual Testing:
echo $DEBUG, echo $APP_ENV/debug, /_debug, /debug/envAutomated Testing:
DEBUG = True in codeExample Test:
# Test that debug mode is disabled in production
def test_debug_disabled_in_production():
import os
os.environ['APP_ENV'] = 'production'
# This should raise ValueError
with pytest.raises(ValueError, match="Debug mode is enabled in a production environment"):
import app # Import triggers startup check
CI/CD Pipeline Check:
# .github/workflows/deploy.yml
- name: Verify No Debug Mode
run: |
if grep -r "DEBUG.*=.*True" app/; then
echo "ERROR: Hardcoded DEBUG=True found"
exit 1
fi
if [ "$APP_ENV" = "production" ] && [ "$DEBUG" = "true" ]; then
echo "ERROR: Debug mode enabled for production deployment"
exit 1
fi
DEBUG = True with env lookupdevelopment
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.