| name | debug-mode-production-anti-pattern |
| description | 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. |
Debug Mode in Production Anti-Pattern
Severity: High
Summary
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.
The Anti-Pattern
This anti-pattern manifests in two primary ways:
- Hardcoded Debug Flags: Global flag
DEBUG = True never changes, so the application runs in debug mode in all environments.
- Unprotected Debug Endpoints: Debug routes (
/debug/env, /_debug/sql) included in production builds provide attack vectors.
BAD Code Example
import os
from flask import Flask, jsonify
app = Flask(__name__)
app.config['DEBUG'] = True
@app.route("/")
def index():
return "Welcome!"
@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()
GOOD Code Example
import os
from flask import Flask, jsonify
app = Flask(__name__)
APP_ENV = os.environ.get('APP_ENV', 'production')
app.config['DEBUG'] = APP_ENV == 'development'
@app.route("/")
def index():
return "Welcome!"
if app.config['DEBUG']:
@app.route("/debug/env")
def debug_env():
return jsonify(os.environ.copy())
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()
JavaScript/Node.js Examples
BAD:
const express = require('express');
const app = express();
const DEBUG = true;
app.get('/', (req, res) => {
res.send('Welcome!');
});
app.get('/debug/env', (req, res) => {
if (DEBUG) {
res.json(process.env);
} else {
res.send('Not in debug mode.');
}
});
app.listen(3000);
GOOD:
const express = require('express');
const app = express();
const APP_ENV = process.env.APP_ENV || 'production';
const DEBUG = APP_ENV === 'development';
app.get('/', (req, res) => {
res.send('Welcome!');
});
if (DEBUG) {
app.get('/debug/env', (req, res) => {
res.json(process.env);
});
}
if (APP_ENV === 'production' && DEBUG) {
throw new Error('FATAL: Debug mode enabled in production. Aborting.');
}
app.listen(3000);
Java/Spring Boot Examples
BAD:
@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:
@RestController
@Profile("dev")
public class DebugController {
@GetMapping("/debug/env")
public Map<String, String> debugEnv() {
return System.getenv();
}
}
@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."
);
}
}
}
Detection
Python/Flask/Django:
DEBUG = True in source code
debug=True in Flask config
DEBUG = True in Django settings.py
- Debug routes:
@app.route("/debug/
JavaScript/Node.js/Express:
const DEBUG = true in source code
process.env.NODE_ENV !== 'production' checks missing
- Debug middleware always enabled
- Routes:
app.get('/debug/
Java/Spring Boot:
debug=true in application.properties
logging.level.root=DEBUG in production
- Debug endpoints without
@Profile("dev")
spring.devtools.restart.enabled=true in prod
PHP:
error_reporting(E_ALL) in production
display_errors = On in php.ini
APP_DEBUG=true in .env
Configuration Files:
.env files with DEBUG=true
- YAML configs with
debug: true
- JSON configs with
"debug": true
Search Patterns:
- Grep:
DEBUG.*=.*[Tt]rue|debug.*:.*true|\/debug\/|process\.env\.NODE_ENV
- Development dependencies in production builds
- Stack traces exposed in error responses
- Verbose error messages with file paths
Prevention
Testing for Debug Mode
Manual Testing:
- Check environment variables:
echo $DEBUG, echo $APP_ENV
- Access debug endpoints:
/debug, /_debug, /debug/env
- Trigger errors and check for stack traces
- Review HTTP headers for debug information (X-Debug, Server versions)
Automated Testing:
- Static Analysis: Semgrep, Bandit (Python), ESLint, SonarQube
- Configuration Scanning: Detect hardcoded
DEBUG = True in code
- Runtime Testing: Burp Suite, OWASP ZAP to find debug endpoints
- CI/CD Checks: Fail builds with debug flags enabled
Example Test:
def test_debug_disabled_in_production():
import os
os.environ['APP_ENV'] = 'production'
with pytest.raises(ValueError, match="Debug mode is enabled in a production environment"):
import app
CI/CD Pipeline Check:
- 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
Remediation Steps
- Identify debug configurations - Use detection patterns above
- Check current environment - Determine if debug mode is active
- Create environment-based config - Use environment variables
- Remove hardcoded flags - Replace
DEBUG = True with env lookup
- Conditional debug routes - Register only in development
- Add startup checks - Abort if debug mode in production
- Test the fix - Verify debug disabled in production config
- Update CI/CD - Add validation to deployment pipeline
Related Security Patterns & Anti-Patterns
References