📋 What Is It?
Security Misconfiguration occurs when APIs are deployed with insecure default configurations, incomplete setups, open cloud storage, misconfigured HTTP headers, verbose error messages, or missing security patches. This is often the result of insecure defaults or incomplete configurations.
API08
OWASP Rank
Config
Focus Area
Easy
To Prevent
⚠️ Common Exploits
- Debug Mode Enabled: Production APIs with debug=True exposing stack traces
- Default Credentials: Admin/admin still active on API gateways
- Verbose Errors: Stack traces revealing file paths and internals
- Missing CORS: Allowing requests from any origin
- Exposed Admin Panels: /admin, /swagger, /actuator publicly accessible
- Unnecessary HTTP Methods: TRACE, OPTIONS enabled without need
- Missing Security Headers: No HSTS, CSP, X-Frame-Options
🔴 Attack Flow
1. Attacker accesses API endpoint
↓
2. Error occurs, debug mode is on
↓
3. Full stack trace returned with paths
↓
4. Discovers internal structure and libs
↓
5. IMPACT: Information leakage aids further attacks!
↓
2. Error occurs, debug mode is on
↓
3. Full stack trace returned with paths
↓
4. Discovers internal structure and libs
↓
5. IMPACT: Information leakage aids further attacks!
❌ Vulnerable Code
// Bad: Debug mode in production!
from flask import Flask
app = Flask(__name__)
app.config['DEBUG'] = True ← NEVER in production!
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
// Bad: CORS allows any origin
from flask_cors import CORS
CORS(app, origins="*") ← Allows any website!
// Bad: Verbose error messages
@app.errorhandler(500)
def handle_error(error):
return jsonify({
'error': str(error),
'traceback': traceback.format_exc() ← Exposes internals!
}), 500
// Bad: Swagger docs in production
// Exposes all endpoints, parameters, schemas
GET /swagger-ui.html ← Publicly accessible!
GET /api-docs ← Complete API documentation!
// Bad: Unnecessary HTTP methods
@app.route('/api/users', methods=['GET', 'POST', 'PUT', 'DELETE', 'TRACE'])
def users():
pass ← TRACE shouldn't be enabled!
✅ Secure Code
// Good: Production configuration
import os
from flask import Flask
app = Flask(__name__)
app.config['DEBUG'] = False ← Always False in prod
app.config['ENV'] = 'production'
// Good: Restricted CORS
from flask_cors import CORS
CORS(app, origins=[
"https://app.example.com",
"https://admin.example.com"
])
// Good: Generic error messages
@app.errorhandler(500)
def handle_error(error):
# Log detailed error internally
logger.error(f"Error: {error}", exc_info=True)
# Return generic message to client
return jsonify({
'error': 'Internal server error',
'code': 'ERR_500'
}), 500
// Good: Secure headers
@app.after_request
def add_security_headers(response):
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['Content-Security-Policy'] = "default-src 'self'"
response.headers['X-XSS-Protection'] = '1; mode=block'
return response
// Good: Protect admin endpoints
if os.getenv('ENVIRONMENT') == 'production':
# Disable Swagger in production
app.config['SWAGGER'] = {'enabled': False}
else:
# Only enable in development
from flask_swagger_ui import get_swaggerui_blueprint
app.register_blueprint(swaggerui_blueprint)
// Good: Only necessary HTTP methods
@app.route('/api/users', methods=['GET', 'POST'])
def users():
if request.method == 'GET':
return get_users()
elif request.method == 'POST':
return create_user()
✓ Prevention Checklist
- Disable debug mode in production
- Remove or secure Swagger/API docs in production
- Implement proper error handling (generic messages)
- Configure restrictive CORS policies
- Add security headers (HSTS, CSP, etc.)
- Disable unnecessary HTTP methods
- Change all default credentials
- Remove stack traces from responses
- Disable directory listing
- Keep software up to date
- Use environment variables for secrets
- Regular security audits and scans
🔍 Detection & Tools
Scanning Tools:
Nmap
Nikto
OWASP ZAP
Burp Suite
SecurityHeaders.com
SSL Labs
Configuration Tools:
Helmet.js
Flask-Talisman
Spring Security
django-csp
ModSecurity
How to Test:
- Check for debug mode by triggering errors
- Access common admin paths (/admin, /swagger)
- Verify security headers are present
- Test CORS with different origins
- Try unnecessary HTTP methods (TRACE, OPTIONS)
- Check for default credentials
🌍 Real-World Breaches
- MongoDB Databases (2017): 27,000+ databases exposed due to default configs
- Elasticsearch Instances: Billions of records exposed via misconfigured servers
- S3 Buckets: Countless data leaks from public S3 buckets
- Docker Registries: Exposed container images with secrets
- Jenkins Servers: Publicly accessible with default credentials
📌 Quick Tips
- DO NOT enable debug mode in production
- DO NOT expose stack traces
- DO NOT use default credentials
- DO add security headers
- DO restrict CORS properly
- DO disable/protect API documentation
- DO regular security scans
📜 Compliance
Related Standards:
- PCI-DSS Requirement 2.2 - Configuration Standards
- NIST 800-53 CM-6 - Configuration Settings
- CIS Benchmarks
- ISO 27001 A.12.6.1
- SOC 2 CC7.1