OWASP Top 10 Deep Dive · 8 of 8

Security Misconfiguration — The Bugs in Your Settings

Most production breaches don't start with a clever exploit — they start with a default password, a debug endpoint left exposed, an S3 bucket flagged "Public", or a permissive IAM policy nobody re-reviewed. The code is fine; the configuration isn't. This category is broad on purpose because the failures are everywhere.

DefaultsS3IAMHeadersTLSDebug Endpoints
← Back to Security
Quick Facts

What Counts

Basic Concepts

  • Defaults left on: default admin passwords, default ports, default sample apps, default credentials in container images.
  • Things exposed that shouldn't be: debug endpoints, actuator routes (Spring Boot /actuator), Kibana with no auth, MongoDB with no password, Redis on the internet.
  • Cloud resources too open: S3 buckets public, security groups 0.0.0.0/0 on port 22, IAM roles with *:*.
  • Missing hardening: no security headers, weak TLS, verbose stack traces, directory listing on, CORS set to *.
  • The unifying property: the platform or framework gave you a default that's convenient for development and dangerous in production. Production is everyone's job to harden.
The Family

The Common Misconfigurations

Default Credentials

admin/admin on a Jenkins, an old Tomcat manager, a Grafana, a router. Internet-wide scanners find these in minutes. Set passwords on every administrative interface. Better: disable the default account and create a new one. Better still: integrate with SSO so there's no local password to forget.

Cloud Storage Left Public

S3 buckets, GCS buckets, Azure blob containers — set "public" on creation, forgotten about. Researchers find tens of thousands of leaked datasets per year this way.

Defenses: AWS S3 Block Public Access at the account level (turns it off org-wide), GCP organization policy storage.publicAccessPrevention, Azure equivalent. Use signed URLs / pre-signed downloads where you genuinely need public-feeling access.

Permissive Security Groups / Firewall Rules

SSH (22), RDP (3389), DB ports (3306, 5432, 27017, 6379, 9200) open to 0.0.0.0/0. Database engines without auth on those ports get owned within minutes of exposure. Use bastion hosts, SSM Session Manager, or VPN; restrict DB ports to private subnets only.

Over-Permissive IAM

"Action": "*", "Resource": "*". Service accounts with admin rights "because I needed to test something." Production roles inheriting development permissions. Run AWS Access Analyzer, GCP Recommender, or open-source equivalents (Cloudsplaining, Parliament) to find the bloat.

Verbose Errors and Debug Pages

Whitelabel error pages with full stack traces, database error messages echoed to clients, DEBUG=True on Django, Whoops on PHP, Spring Boot's actuator with /heapdump available. All gold for attackers — they reveal versions, paths, internal hostnames, sometimes credentials.

Fix: production builds turn debug off, return generic errors to clients, log full traces server-side only.

CORS Wide Open

Access-Control-Allow-Origin: * with Allow-Credentials: true means any site on the internet can make authenticated requests as your users. The combination is forbidden by spec but still misconfigured. Allow-list specific origins; don't reflect the request's Origin header without checking.

Missing Security Headers

HTTPS-only without Strict-Transport-Security means an attacker on the same Wi-Fi can downgrade. Other headers worth setting:

  • Content-Security-Policy — blocks XSS even if it gets through.
  • X-Content-Type-Options: nosniff — stops MIME confusion.
  • Referrer-Policy: strict-origin-when-cross-origin — limits leaked URLs.
  • Permissions-Policy — turn off browser features you don't use (camera, mic, geolocation).
  • X-Frame-Options or CSP frame-ancestors — prevent clickjacking.
Outdated TLS Configurations

TLS 1.0/1.1 enabled, weak ciphers, no HSTS preload. Mozilla's "Modern" config and SSL Labs' tester give you a 5-minute fix. TLS 1.2+ only; prefer TLS 1.3 where supported; ECDHE+AES-GCM ciphers.

Sample Apps and Test Endpoints

/test, /debug, /admin/h2-console, /swagger-ui with full schema, /graphql introspection on in production. None of these are bugs; all are doors. Either remove them, gate them behind auth, or restrict to internal networks.

Container and Image Misconfig
  • Containers running as root.
  • Bind-mounting /var/run/docker.sock into a container (= host root).
  • Privileged containers without need.
  • Images with build secrets baked in (docker history reveals them).
  • K8s pods with hostNetwork: true or hostPath mounts.

Tools: Trivy, kube-bench, kube-hunter, Falco, OPA/Gatekeeper, Kyverno. Wire policies that fail-closed in CI.

Defenses

The Working Posture

1. Infrastructure as Code, Reviewed

Click-ops creates one-off snowflakes nobody can audit. Terraform / Pulumi / CloudFormation / Bicep with peer review puts every config change through PR review and history. Pair with policy-as-code (OPA, Sentinel, Checkov) to fail builds that violate guardrails.

2. Hardened Baseline Images and Templates

Don't start from "Ubuntu latest"; start from your org's hardened base. CIS Benchmarks codified for your platform, applied via image build. Distroless or minimal base images shrink the attack surface dramatically.

3. Secrets in a Manager, Never in Config

AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, HashiCorp Vault, Doppler. Apps fetch at runtime via IRSA / Workload Identity / mTLS. Rotate on a schedule and on every employee offboarding. Git-leaks scanning in CI catches accidental commits before they hit main.

4. Continuous Configuration Scanning

AWS Security Hub, Prowler, ScoutSuite, Wiz, Lacework, Orca for cloud posture. Trivy / Checkov / Terrascan in CI for IaC. Internal Kubernetes scanning (Falco, kube-bench) at runtime. Score over time; reduce critical findings month over month.

5. Different Configs by Environment, Same Defaults

Dev should be as close to prod as possible without being prod. Hard-code "production" defaults — TLS, secure cookies, auth required — and override locally for development, not the other way around. Otherwise the day you forget to flip a flag, prod ships with dev settings.

6. Periodic Audit and Cleanup

Misconfig accumulates. Quarterly review: open security groups, unattached EBS volumes, dormant accounts, stale IAM roles, sample apps that survived an old POC, public S3 buckets. Most breaches start in things nobody owns anymore.

Continue

Other OWASP Top 10