API Security in Depth · Configuration, Inventory & Secure Operations
Security Misconfiguration: TLS, CORS, Headers & Errors
Hardened defaults for every API deployment.
Common API misconfigurations: permissive CORS (reflecting any Origin with credentials), verbose errors with stack traces, debug endpoints in production (Spring Actuator, /docs with secrets), missing TLS or old ciphers, default credentials on gateways, missing security headers, and unnecessary HTTP methods. Fix them with hardened templates, config scanning in CI, and environment-specific settings reviewed like code.
Misconfiguration checklist
| Setting | Bad | Good |
|---|---|---|
| CORS | Access-Control-Allow-Origin: <reflected> + credentials | Explicit origin allowlist; no credentials for public APIs |
| Errors | Stack traces, SQL in responses | RFC 9457 problem details + request ID; details in logs |
| TLS | TLS 1.0/1.1 allowed | TLS 1.2+ (prefer 1.3), HSTS |
| Management endpoints | Public /actuator, /metrics | Separate port/network, auth |
| API docs | Exposed with try-it on prod admin APIs | Public docs only for public APIs |
| Headers | None | Content-Type: application/json; X-Content-Type-Options: nosniff; Cache-Control: no-store for sensitive responses |
app.add_middleware(
CORSMiddleware,
allow_origins=["https://app.example.com", "https://admin.example.com"], # no "*" with credentials
allow_credentials=True,
allow_methods=["GET", "POST", "PATCH", "DELETE"],
allow_headers=["Authorization", "Content-Type", "Idempotency-Key"],
max_age=600,
)
server:
error: { include-stacktrace: never, include-message: never }
management:
server: { port: 9090 } # internal only
endpoints.web.exposure.include: health,prometheus
springdoc:
api-docs.enabled: false # for internal/admin APIs
Common pitfalls
- Reflecting the Origin header with credentials allowed.
- Same config for dev and prod.
- Leaving framework debug modes on.
Key points
- Explicit CORS allowlists
- Generic errors, detailed logs
- Lock down management endpoints
Further reading: OWASP API8:2023
Practice questions
Why is reflecting the Origin header with Access-Control-Allow-Credentials dangerous?
Answer
Any website can then make credentialed requests to your API from a victim's browser and read the responses.
Where should detailed error information go instead of the response?
Answer
Into server logs/traces linked by a request ID that the response includes.
Open in the app to mark lessons complete, take notes and track your progress.