mediumSeverity: mediumRisk ratingHow usable this gap is to an attacker. Severity sets the posture penalty: critical โˆ’40, high โˆ’20, medium โˆ’10, low โˆ’4, info โˆ’1. Higher severity means fix it sooner.App server / gateway configWhere it livesImplementationThis fix is applied in: App server / gateway config. That's the surface you'll edit, DNS, response headers, or a static file.~10 minTime to fixEffortRoughly 10 minutes of hands-on work, propagation aside. Most of these are copy-paste.+10 posture+10 postureScore impactPoints this fix recovers in the ApeCyber posture score (0โ€“100). Posture = 100 minus the severity penalty of every open finding; clearing this finding adds these points back.

Exposed API docs: stop publishing the map of every endpoint

Gating Swagger/OpenAPI behind auth (or turning it off in production) removes a complete map of your API.

The threat

The scanner requested a docs path (a Swagger UI page or an OpenAPI schema like /openapi.json or /v3/api-docs) and got the document back. Interactive API docs are wonderful in development and normal to leave on by a framework default, which is exactly why they so often ship to production by accident.

Public, that schema is a complete, annotated map of your API: every endpoint, every HTTP method, every parameter and its type, request and response shapes, and the auth scheme each route expects. It is the reconnaissance an attacker would otherwise have to assemble by hand, handed over in one file, pointing straight at the endpoints worth probing.

The exact fix

Turn the docs off in production, or put them behind authentication. Turning them off is the common choice.

Disable in production (pick your framework):

# Spring Boot (springdoc)
springdoc.api-docs.enabled=false
springdoc.swagger-ui.enabled=false
// ASP.NET (Swashbuckle): only in development
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}
// Express (swagger-ui-express): skip in production
if (process.env.NODE_ENV !== 'production') {
    app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(spec));
}
# FastAPI: no docs endpoints in production
app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)

If you need docs in production, require auth. Put them behind basic auth at the gateway, SSO, or an internal-only route, and block the public schema paths (/swagger*, /openapi.json, /v3/api-docs) at your reverse proxy.

Hiding the map does not lock the doors. Every endpoint the docs revealed is still live. Use this as the prompt to confirm each one actually enforces authorization, because an attacker can hit those routes whether or not the docs are visible.

Verify it

curl -s -o /dev/null -w '%{http_code}\n' https://yourdomain.com/openapi.json

You want 404 (off) or 401/403 (gated). Check /swagger-ui.html and /v3/api-docs too; none should return a 200 with a body containing "openapi": or "swagger":.

Proof

The ApeCyber scanner catches an open schema with a single GET from the outside, touching nothing, on every scan. A production API should answer that request with a 404 or an auth challenge, never a full endpoint map, and closing this recovers a clean โˆ’10 on the posture score.