๐ What Is It?
Security Misconfiguration arises when an application, or any layer it depends on, ships with insecure settings: unsafe defaults, security controls never switched on, overly broad permissions, sample or admin components left installed, or verbose behaviour that leaks internal detail. It is not one bug in your code โ it is the accumulated gap between how a system can be hardened and how it was actually deployed.
A02
OWASP Rank
Defaults
Root Cause
Easy
To Prevent
โ ๏ธ Common Attack Vectors
- Fingerprinting via banners & headers (Server, X-Powered-By)
- Default / sample credentials (admin/admin)
- Verbose errors & debug console (leads to RCE)
- Directory listing & exposed .git / .env / backups
- Overly permissive CORS (reflected Origin + credentials)
- XXE and unpatched / outdated components
๐ด Attack Flow
1. Fingerprint: banner reveals a debug build
โ
2. Trigger error: stack trace confirms debug on
โ
3. Interactive console executes code as www-data
โ
4. Console reads .env, yielding cloud IAM keys
โ
5. IMPACT: pivot to cloud, drain buckets!
โ
2. Trigger error: stack trace confirms debug on
โ
3. Interactive console executes code as www-data
โ
4. Console reads .env, yielding cloud IAM keys
โ
5. IMPACT: pivot to cloud, drain buckets!
โ Vulnerable Code
from flask import Flask
app = Flask(__name__)
if __name__ == "__main__":
# debug=True in prod -> interactive console = RCE
app.run(host="0.0.0.0", port=5000, debug=True)
โ Secure Code
import os
from flask import Flask, jsonify
app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ["APP_SECRET_KEY"]
app.config["DEBUG"] = False
@app.errorhandler(500)
def server_error(e):
app.logger.exception(e) # detail to logs
return jsonify(error="Internal Server Error"), 500
# Run behind gunicorn/uwsgi, never the dev server
โ Prevention Checklist
- Start from a hardened CIS/STIG baseline in IaC
- Remove unused modules, ports, sample apps
- Change all default credentials; use a secrets manager
- Debug off; generic client errors; detail in logs only
- Set HSTS, CSP, nosniff, Referrer-Policy on every response
- Disable directory listing; keep .git / .env unreachable
- Explicit CORS allow-list; never reflected origin + creds
- Disable DTDs / external entities in XML parsers
- Segment tiers; least privilege; isolate management plane
- Verify config, headers & TLS continuously in CI
๐ Real-World & Pitfalls
The former XXE category (A4:2017) is merged here โ always disable DTDs and external entities in XML parsers.
Common pitfall: Leaving
Common pitfall: Leaving
debug=True on a production Flask/Django app exposes an interactive console that is direct remote code execution. Ship with debug off and run behind a real WSGI server.
๐ Tools & Takeaway
nuclei
nikto
feroxbuster
Shodan
Trivy
testssl.sh
Key Takeaway: Defaults are chosen to make software start, not to make it safe. Start from a hardened baseline, codify it so every environment is identical, and verify continuously โ an untested baseline drifts back to insecure.