Misconfiguration

OWASP Top 10

Course 1 · Chapter 5 · A05: Security Misconfiguration

A04 was about flawed designs. A05 Security Misconfiguration is about the opposite failure: the design and code can be perfectly secure, but the system is left in an insecure state through how it's set up, deployed, or maintained. It's one of the most common categories precisely because modern apps have enormous configuration surfaces — frameworks, servers, cloud services, containers, databases — and any one of them left in an unsafe state is a hole.

A05: Security Misconfiguration — Secure App, Unsafe Setup

Misconfiguration means the application stack is not hardened, or is configured insecurely, anywhere across its layers. The code may be flawless; the configuration is the vulnerability. This category rose in 2021 as systems grew more complex and more highly configurable (cloud, IaC, microservices) — more knobs means more knobs to get wrong.

The Common Misconfigurations

MisconfigurationWhy it's dangerous
Default credentialsadmin/admin, default DB/router/CMS passwords left unchanged — instant access
Verbose errors / debug modestack traces leak versions, paths, queries (accelerates other attacks)
Unnecessary features enabledunused ports, services, sample apps, admin consoles — extra attack surface
Open cloud storagepublic S3 buckets / blobs exposing data to the whole internet
Missing security headersno HSTS, CSP, X-Content-Type-Options, etc. — weakens browser protections
Directory listing / exposed files.git, .env, backups, config files reachable over HTTP
Overly permissive settingswildcard CORS, permissive file perms, debug endpoints in prod
Outdated/insecure defaultsshipped configuration that was never hardened for production

Two Classics Worth Dwelling On

Default Credentials

Shipping or deploying with default/unchanged credentials (admin/admin, a database's default root password, a router's factory login) is one of the oldest and still-common breaches. Attackers scan the internet for known default logins; an exposed admin panel with factory credentials is found in minutes, automatically. Every default credential must be changed before exposure, and ideally accounts ship disabled or force a password set on first use.

Verbose Errors & Debug Mode in Production

A debug stack trace is a free map for the attacker
Leaving detailed error pages or framework debug mode on in production leaks a wealth of intelligence: the exact framework and version (→ A06 known-vuln lookup), file paths and directory structure, database type, and sometimes the failing SQL query or environment variables. It accelerates nearly every other attack (you saw this in the SQLi course — verbose DB errors map the schema). The fix is the recurring pattern: show users a generic error, log the details server-side. Debug mode is for development only; shipping it to production is a textbook misconfiguration (real frameworks have leaked secrets this way via their debug consoles).

Security Headers — Cheap, High-Value Hardening

A specific, easy-to-fix slice of A05: HTTP response headers that switch on browser-side protections. Missing them is a misconfiguration; adding them is usually a few lines:

Strict-Transport-Security: max-age=31536000; includeSubDomains # HSTS — force HTTPS Content-Security-Policy: default-src 'self'; ... # CSP — limit script sources (XSS) X-Content-Type-Options: nosniff # stop MIME-sniffing X-Frame-Options: DENY (or CSP frame-ancestors) # clickjacking defence Referrer-Policy: strict-origin-when-cross-origin # limit referrer leakage

These tie back to earlier courses — HSTS and CSP appeared in the HTTPS and XSS courses respectively. From A05's view they're configuration: present-and-correct, or a missing hardening step. Tools like securityheaders.com and Mozilla Observatory grade them.

The Defences: Hardening & Repeatability

  • Harden every layer — OS, web server, app framework, database, cloud services, containers — following each vendor's hardening guidance / a benchmark (CIS Benchmarks).
  • Change all defaults — credentials, keys, sample content; remove default/sample accounts and apps.
  • Minimize surface — disable/uninstall unused features, ports, services, and admin endpoints; least functionality.
  • Generic errors in prod, debug off — detailed errors logged server-side only.
  • Set security headers — HSTS, CSP, nosniff, frame-ancestors, etc.
  • Lock down storage — no public buckets unless intended; correct file/object permissions; block access to .git/.env/backups.
The real fix is automation: configuration as code, not by hand
Manual configuration drifts — one server gets hardened, the next doesn't; a setting changed for debugging never gets reverted; "secure" environments diverge over time. The durable answer to A05 is repeatable, automated configuration: define the hardened state as code (Infrastructure as Code — Terraform/Ansible, hardened container base images, locked-down framework config in version control) so every environment is provisioned identically and securely, and drift is detectable. Add automated configuration scanning (cloud posture tools, header checkers, container/image scanners) in CI to catch regressions. A misconfiguration you can re-introduce by hand is one you'll re-introduce; make the secure state the default, reproducible state. (This also connects to A08 — pipeline/build integrity.)

Hands-On Exercises

Exercise 1

Identify the misconfiguration and its risk in each: (a) a new admin panel still using admin/admin; (b) production returning full stack traces; (c) a publicly-readable S3 bucket of user uploads; (d) .env reachable at /.env. State the fix for each and which other Top 10 category it can amplify.

📄 View solution
Exercise 2

List the key security headers (HSTS, CSP, X-Content-Type-Options, frame-ancestors/X-Frame-Options, Referrer-Policy), what each does, and which earlier course/attack it relates to. Explain why "missing headers" counts as a misconfiguration rather than a code bug.

📄 View solution
Exercise 3

Explain why manual, per-server configuration is the root of recurring misconfiguration, and how "configuration as code" + automated scanning fixes it. Give a concrete example of configuration drift and how IaC prevents it. Connect this to secure defaults (A04) and pipeline integrity (A08).

📄 View solution

Chapter 5 Quick Reference

  • A05 Security Misconfiguration — secure code, but the system is left in an insecure state; common because the config surface is huge (frameworks, servers, cloud, containers)
  • Common: default credentials · verbose errors/debug in prod · unused features enabled · open cloud storage · missing security headers · exposed .git/.env/backups · wildcard CORS/permissive settings
  • Default creds — scanned-for and breached in minutes; change every default before exposure
  • Debug/verbose errors leak framework version, paths, queries → fuels other attacks; show generic errors, log details server-side
  • Security headers (HSTS, CSP, nosniff, frame-ancestors, Referrer-Policy) — cheap high-value hardening; missing = misconfiguration
  • Defences: harden every layer (CIS Benchmarks) · change defaults · minimize surface · lock down storage · set headers
  • The durable fix is automation — configuration as code (IaC, hardened images, versioned config) + config scanning in CI, so every environment is identical, hardened, and drift is caught
  • Next chapter: A06 Vulnerable & Outdated Components — dependency & supply-chain risk