📋 What Is It?
Security Misconfiguration occurs when security settings are defined, implemented, deployed, or maintained incorrectly. This includes default configurations, incomplete setups, open cloud storage, verbose error messages, and missing security headers.
#5
OWASP Rank
90%
Apps Tested
208K
Occurrences
⚠️ Common Exploits
- Default Credentials: Unchanged admin/admin passwords
- Debug Mode: Exposed stack traces and sensitive info
- Missing Headers: No CSP, HSTS, X-Frame-Options
- Directory Listing: Browsing server directories
- Verbose Errors: Detailed error messages reveal system info
- Open Cloud Storage: Public S3 buckets with sensitive data
🔴 Attack Flow
1. App deployed with DEBUG=True
↓
2. Attacker triggers error (404, 500)
↓
3. Stack trace reveals code paths & secrets
↓
4. Attacker finds database credentials
↓
5. BREACH: Full database access!
↓
2. Attacker triggers error (404, 500)
↓
3. Stack trace reveals code paths & secrets
↓
4. Attacker finds database credentials
↓
5. BREACH: Full database access!
❌ Vulnerable Code
// Bad: Debug mode enabled in production
from flask import Flask
app = Flask(__name__)
app.config['DEBUG'] = True # Exposes stack traces!
app.config['SECRET_KEY'] = 'default-key' # Default secret!
// Bad: No security headers
@app.route('/')
def index():
return render_template('index.html')
# Missing CSP, HSTS, X-Frame-Options
// Bad: Default error handling
# Shows full stack trace to users
✅ Secure Code
// Good: Proper production configuration
import os
from flask import Flask
app = Flask(__name__)
app.config['DEBUG'] = False # Disable debug mode
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
// Good: Security headers middleware
@app.after_request
def set_security_headers(response):
response.headers['Strict-Transport-Security'] = \
'max-age=31536000; includeSubDomains'
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['Content-Security-Policy'] = \
"default-src 'self'"
return response
// Good: Custom error pages (no stack traces)
@app.errorhandler(500)
def handle_error(error):
return render_template('error.html'), 500
✓ Prevention Checklist
- Disable debug mode in production
- Remove/change all default credentials
- Apply security headers (CSP, HSTS, X-Frame-Options)
- Disable directory listing
- Use custom error pages (no stack traces)
- Remove unnecessary features/services
- Keep all software updated
- Implement automated configuration scanning
- Use environment-specific configurations
- Regular security audits and hardening
🔍 Detection & Tools
Scanning Tools:
Nessus
OpenVAS
Nikto
SecurityHeaders.com
Hardening Tools:
Ansible
Chef
Docker Bench
CIS Benchmarks
How to Test:
- Check securityheaders.com for missing headers
- Try default credentials on admin panels
- Trigger errors to see if stack traces appear
- Scan for open ports and unnecessary services
🌍 Real-World Breaches
- Elasticsearch (2020): 5 billion records exposed due to unsecured databases
- Capital One (2019): 100M+ records via misconfigured AWS WAF
- Facebook (2019): 540M records on public AWS S3 bucket
- MongoDB (2017): Thousands of unsecured databases exposed online
📌 Quick Tips
- DO NOT use default credentials
- DO NOT enable debug in production
- DO implement security headers
- DO use custom error pages
- DO regularly scan configurations
📜 Compliance
Related Standards:
- PCI-DSS Requirement 2.2
- CIS Critical Controls 3, 5
- NIST 800-53 CM-6, CM-7
- ISO 27001 A.12.6