Install
$ agentstack add skill-igbuend-grimbard-debug-mode-production-anti-pattern ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
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 = Truenever 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
# 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()
GOOD Code Example
# 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()
JavaScript/Node.js Examples
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);
Java/Spring Boot Examples
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 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 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."
);
}
}
}
Detection
Python/Flask/Django:
DEBUG = Truein source codedebug=Truein Flask configDEBUG = Truein Django settings.py- Debug routes:
@app.route("/debug/
JavaScript/Node.js/Express:
const DEBUG = truein source codeprocess.env.NODE_ENV !== 'production'checks missing- Debug middleware always enabled
- Routes:
app.get('/debug/
Java/Spring Boot:
debug=truein application.propertieslogging.level.root=DEBUGin production- Debug endpoints without
@Profile("dev") spring.devtools.restart.enabled=truein prod
PHP:
error_reporting(E_ALL)in productiondisplay_errors = Onin php.iniAPP_DEBUG=truein .env
Configuration Files:
.envfiles withDEBUG=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
- [ ] Use environment variables to control debug mode and other environment-specific settings.
- [ ] Never hardcode
DEBUG = True. - [ ] Conditionally register debug routes so they are not included in production builds.
- [ ] Implement a startup check in the application that aborts if it detects debug mode is enabled in a production environment.
- [ ] Use separate configuration files for each environment (development, staging, production) to avoid overlap.
- [ ] Review your CI/CD pipeline to ensure that the correct environment variables are being injected and that development artifacts are excluded from the final build.
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 = Truein code - Runtime Testing: Burp Suite, OWASP ZAP to find debug endpoints
- CI/CD Checks: Fail builds with debug flags enabled
Example 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
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 = Truewith 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
- [Verbose Error Messages Anti-Pattern](../verbose-error-messages/): A common consequence of running in debug mode.
- [Hardcoded Secrets Anti-Pattern](../hardcoded-secrets/): Secrets are often exposed through debug information.
- [Missing Security Headers Anti-Pattern](../missing-security-headers/): Can provide defense-in-depth by controlling how browsers handle content.
References
- OWASP Top 10 A02:2025 - Security Misconfiguration
- OWASP GenAI LLM02:2025 - Sensitive Information Disclosure
- OWASP API Security API8:2023 - Security Misconfiguration
- CWE-215: Debug Information Exposure
- CAPEC-121: Exploit Non-Production Interfaces
- Source: sec-context
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: igbuend
- Source: igbuend/grimbard
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.