Security Misconfiguration Testing: How to Find OWASP A05 Vulnerabilities
Security misconfiguration is OWASP's fifth most critical web application vulnerability — and arguably the most preventable. Unlike injection or broken access control, misconfiguration doesn't require exploiting a logic flaw. It exploits the gap between what a system does by default and what it should do in production.
The attack surface is enormous: web servers, application frameworks, databases, cloud storage, container runtimes, API gateways, TLS configurations, HTTP security headers, error handling, and every piece of software in your stack that ships with a default configuration designed for developer convenience rather than production security.
This guide covers how to test for security misconfiguration systematically — what patterns to look for, which tools to use, and what good remediation looks like.
What Security Misconfiguration Covers
A05 is a category that spans multiple distinct patterns. They share a common root cause — insecure defaults, incomplete hardening, or drift between environments — but each requires a different testing approach.
admin/admin, admin/password, vendor-specific defaults that are publicly documented. Databases, admin consoles, IoT devices, and third-party integrations are the common sources.
Access-Control-Allow-Origin: * on APIs that handle authenticated requests, or origins that reflect the request's Origin header without validation. This allows any website to make credentialed cross-origin requests to your API.
Testing Methodology
1. Enumerate the attack surface
Start by mapping everything that could be misconfigured. For a web application, that includes:
- All HTTP response headers across every endpoint type (login, API, static, error)
- The TLS configuration (protocol versions, cipher suites, certificate details)
- Error handling: what do 404, 500, and validation errors expose?
- Robots.txt, sitemap.xml, and well-known URIs (they map your structure)
- Any admin interface, debug endpoint, or management console
- Default paths for common frameworks:
/swagger-ui,/actuator,/phpmyadmin,/wp-admin
2. Test HTTP security headers
Use curl -I or a browser's Network tab to inspect response headers on representative pages. The minimum baseline for production:
| Header | Expected value | Missing = risk |
|---|---|---|
Strict-Transport-Security |
max-age=31536000; includeSubDomains |
SSL stripping, downgrade attacks |
Content-Security-Policy |
Restrictive policy with no unsafe-inline |
XSS escalation, data exfiltration |
X-Frame-Options |
DENY or SAMEORIGIN |
Clickjacking |
X-Content-Type-Options |
nosniff |
MIME-type sniffing attacks |
Referrer-Policy |
strict-origin-when-cross-origin |
Sensitive URL leakage to third parties |
Permissions-Policy |
Restrict camera, microphone, geolocation | Browser feature abuse |
Server |
Absent or generic | Version fingerprinting, targeted attacks |
Also look for headers that reveal implementation details: X-Powered-By: Express 4.18.2, X-AspNet-Version, X-Generator: WordPress 6.4. These are information disclosure findings even when they don't directly enable exploitation.
3. Test TLS configuration
Use testssl.sh or Nmap's ssl-enum-ciphers script to enumerate the TLS configuration:
# testssl.sh — comprehensive TLS audit
testssl.sh https://target.example.com
# Nmap cipher enumeration
nmap --script ssl-enum-ciphers -p 443 target.example.com
# OpenSSL manual check for old protocol support
openssl s_client -connect target.example.com:443 -tls1
openssl s_client -connect target.example.com:443 -tls1_1
Look for: TLS 1.0 or 1.1 still supported, weak cipher suites (RC4, DES, 3DES, EXPORT ciphers), self-signed or expired certificates, missing OCSP stapling, and the absence of HSTS preloading.
4. Check for exposed administrative interfaces
Run path discovery against the web root with a focused wordlist targeting common admin interfaces and framework defaults:
# Common admin and management paths
ffuf -u https://target.example.com/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/common.txt \
-mc 200,301,302,403 \
-t 40
# Framework-specific paths
# Spring Boot Actuator
curl -s https://target.example.com/actuator | jq
curl -s https://target.example.com/actuator/env
curl -s https://target.example.com/actuator/heapdump
# Express / Node debug
curl https://target.example.com/debug
curl https://target.example.com/__debug__
# Django debug
curl https://target.example.com/admin/
# PHP info
curl https://target.example.com/phpinfo.php
curl https://target.example.com/info.php
Spring Boot Actuator deserves special attention. The /actuator/env endpoint exposes environment variables (including secrets), /actuator/heapdump returns a heap dump that can be parsed for in-memory secrets, and /actuator/mappings maps every endpoint in the application.
5. Test for default credentials
If you discover an admin interface, CMS login, or database management tool, test common default credentials before attempting anything else. Vendor default credentials are documented in public databases like CIRT.net and SecLists.
# Common defaults worth trying manually
admin / admin
admin / password
admin / 123456
admin / (empty)
root / root
root / (empty)
guest / guest
# Service-specific defaults
# phpMyAdmin: root / (empty), root / root
# WordPress: admin / admin
# Jenkins: admin / admin (older installs)
# Grafana: admin / admin
# Kibana: elastic / changeme
In a black-box engagement, try default credentials against every login surface you find before escalating to more complex attacks. The ROI is enormous — it takes 30 seconds and can yield full administrative access.
6. Test CORS configuration
CORS misconfigurations range from "wildcard on unauthenticated endpoints" (low risk) to "reflects arbitrary origins on endpoints that handle authenticated sessions" (high risk). Test by sending a request with a crafted Origin header and checking what the server returns:
# Test whether the server reflects the Origin header
curl -s -I -H "Origin: https://evil.example.com" \
https://target.example.com/api/v1/user/profile
# Look for:
# Access-Control-Allow-Origin: https://evil.example.com (reflected — bad)
# Access-Control-Allow-Credentials: true (combined with above = critical)
# Access-Control-Allow-Origin: * (wildcard — risky on auth endpoints)
The dangerous combination is Allow-Origin: (your-crafted-origin) plus Allow-Credentials: true. This allows any page on evil.example.com to make credentialed requests to the API and read the responses — effectively bypassing the browser's same-origin policy for your authenticated users.
7. Test error handling
Trigger errors deliberately and observe what the application reveals:
- Request a non-existent page (
/definitely-does-not-exist-xyz) — does the 404 reveal stack traces, file paths, or framework version? - Submit malformed input to a form — do validation errors expose database schema or internal variable names?
- Send invalid JSON to an API — does the error message reveal the backend language and framework?
- Trigger a server error by sending extreme values — what does the 500 error page expose?
Cloud Storage Checks
If the application stores files or assets in cloud object storage, check whether the bucket/container is publicly accessible. This is one of the highest-impact misconfigurations in existence — publicly readable buckets containing customer data have caused breaches affecting tens of millions of records.
# AWS S3 — check if bucket is publicly accessible
aws s3 ls s3://bucket-name --no-sign-request
# Test via URL (publicly accessible bucket returns a listing)
curl -s https://bucket-name.s3.amazonaws.com/
# Google Cloud Storage
gsutil ls -r gs://bucket-name
# Azure Blob Storage — test for public container access
curl -s "https://accountname.blob.core.windows.net/containername?restype=container&comp=list"
Even if the bucket is private, check whether individual object URLs are guessable. Some applications generate "secure" file URLs using predictable naming patterns (timestamps, sequential IDs, user IDs) rather than cryptographic tokens.
What Automated Scanners Catch
Security misconfiguration is one of the categories where automated scanners genuinely excel. Most findings are deterministic: a header is either present or it isn't; a cipher suite either appears in the negotiation or it doesn't.
| Finding type | Automated detection | Notes |
|---|---|---|
| Missing security headers | Excellent | Trivially enumerable; well-documented expected values |
| Weak TLS configuration | Excellent | testssl.sh and similar tools provide complete coverage |
| Exposed admin interfaces | Good | Wordlist-based discovery covers common paths; custom paths missed |
| Verbose error messages | Good | Scanners trigger errors deliberately and parse responses for stack traces |
| Default credentials | Moderate | Scanners try known defaults; novel or vendor-specific defaults may be missed |
| CORS misconfiguration | Good | Origin reflection testing is automatable; impact assessment is context-dependent |
| Cloud storage exposure | Limited | Requires cloud credentials or known bucket names; not from web scanning alone |
| Environment-specific config drift | None | Requires comparing dev/staging/prod configurations — not externally observable |
Security Misconfiguration in CI/CD Pipelines
Modern applications introduce misconfigurations not just in runtime config but in the build and deployment pipeline itself. Things to check that automated web scanners won't reach:
- Secrets in environment variables — API keys, database passwords, and private keys exposed via
/actuator/envor similar diagnostic endpoints - Docker image layers — secrets accidentally baked into image layers during build, retrievable via
docker history - Permissive CI/CD webhooks — pipeline triggers that can be activated by unauthenticated actors, potentially enabling malicious builds
- Public artifact registries — container images or build artifacts stored in registries with public read access, exposing internal code or embedded secrets
Security Misconfiguration Checklist
- Audit all HTTP security headers: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
- Run a full TLS audit (testssl.sh) — disable TLS 1.0/1.1, remove weak cipher suites
- Remove or disable all server version headers (Server, X-Powered-By, X-AspNet-Version)
- Enumerate hidden admin interfaces and framework default paths
- Verify default credentials are changed on all third-party components and admin consoles
- Test CORS configuration — check for origin reflection with credentials on API endpoints
- Trigger deliberate errors and confirm no stack traces, database errors, or internal paths are exposed
- Verify directory listing is disabled on all web-accessible directories
- Confirm cloud storage buckets are private; audit object URL predictability
- Check robots.txt and sitemap.xml do not expose sensitive paths
- Validate that debug features, diagnostic endpoints, and development tools are disabled in production
- Confirm environment-specific configuration (dev vs. staging vs. prod) is properly separated
What Good Remediation Looks Like
Security misconfiguration is a process problem as much as a configuration problem. Individual findings are easy to fix; preventing new ones from appearing requires discipline:
- Hardening baselines — define an approved security configuration for every component type (web server, database, container runtime) and enforce it via infrastructure-as-code, not manual documentation
- Environment parity — staging should be as close to production as possible; every difference is a potential "I forgot to change this in prod" finding
- Automated header testing in CI — run security header checks as part of the deployment pipeline so regressions fail the build before they reach production
- Secrets management — no secrets in environment variables, image layers, or config files. Use a secrets manager (Vault, AWS Secrets Manager, Azure Key Vault) and rotate credentials on a schedule
- Dependency scanning — check the default configurations of third-party libraries and frameworks; don't assume a library is secure by default because it's popular
- Regular scanning — misconfiguration drifts in. Run automated scans against production on a schedule, not just before releases
Ironimo checks for security misconfiguration on every scan — HTTP security headers, TLS configuration, exposed admin interfaces, verbose error handling, and CORS configuration — using the same Kali Linux toolset professional pentesters run against production applications.
Schedule on-demand or recurring scans against your staging or production environment. Results include the exact finding, severity, and a remediation path so your team can act immediately.
Start free scan