Questions
What should I check before exposing an API publicly?
Before an API becomes publicly reachable, check it the way an anonymous client will see it: what each endpoint returns without credentials, which browser origins are allowed to call it with credentials, what its error responses reveal, whether it limits how fast one client can call it, and whether any response carrying user data is marked cacheable by shared caches. Each of these is observable from outside, which is exactly why it has to be right before the API is.
What an anonymous request returns
Call every endpoint without credentials and read what comes back. Anything that is not meant to be public should answer 401 or 403, not data.
An endpoint that returns a list of records to an anonymous caller is the most common serious finding on a newly exposed API.
Check object identifiers too: an endpoint that returns a record for any identifier supplied, without checking ownership, is exposed even when it requires a login.
Older versions of the API still deployed alongside the new one are part of the surface, and frequently the part with weaker checks.
Only HTTPS should answer; an HTTP listener that serves the API unencrypted undoes everything else.
Which origins may call it from a browser
Cross-origin rules decide which web pages may read the API's responses in a visitor's browser.
A wildcard origin is acceptable for genuinely public, unauthenticated data and for nothing else.
An API that reflects whatever origin the request names, while also allowing credentials, lets any website read a logged-in visitor's data.
Responses that vary by origin must say so in the Vary header, or a cache may serve one origin's permission to another.
Preflight requests should be answered deliberately, with the methods and headers the API actually accepts.
What errors reveal
Error responses should describe the problem to the caller, not the implementation to an attacker.
Stack traces, framework names, file paths, SQL fragments and internal host names in error bodies are all common on APIs promoted from internal use.
A consistent, structured error format — such as problem details — gives callers what they need without the internals.
Probe with malformed input, wrong types and missing fields, since those are the paths that produce the most revealing errors.
How it limits use
Without a rate limit, a single client can consume capacity meant for everyone and enumerate anything enumerable.
A limited request should answer 429, ideally with a Retry-After header so well-behaved clients back off correctly.
Headers stating the limit and the remaining allowance let clients stay under it without guessing.
Authentication endpoints deserve a stricter limit than read endpoints, since they are what credential-stuffing tools call.
What caches may keep
A response containing one user's data must not be storable by shared caches, or the next caller may receive it.
Mark such responses private or no-store explicitly; relying on a default is how user data ends up on a CDN.
Public, identical-for-everyone responses can and should be cacheable, which is the cheapest capacity available.
Check the behaviour through the CDN as well as at the origin, since the CDN may apply its own rules.
What the documentation reveals
A published API description tells integrators how to call the API — and tells everyone else every endpoint and parameter.
That is fine for a public API and a leak for an internal one that became reachable by accident.
If a description is published, it should match what is deployed; drift between the two usually means undocumented endpoints nobody is reviewing.
The authentication schemes it declares should match those the API actually enforces.
Versioning should be explicit, so a breaking change does not have to be made in place on a live public interface.
Frequently asked questions
- Is a wildcard CORS origin always wrong?
- No. For public, unauthenticated data it is appropriate. It is wrong combined with credentials, and a server that echoes any origin while allowing credentials is worse than a wildcard.
- Should my API documentation be public?
- If the API is meant for third parties, yes. If it is internal, a published description is a map of the whole surface, and its presence is a sign the API is more exposed than intended.
- Why check caching on an API?
- Because a response with one user's data that a shared cache is allowed to store can be served to the next caller. It has to be marked private or no-store.
Sources
Related
- Public API endpoint
- CORS wildcard with credentials
- Stack traces in responses
- User data cached publicly
- REST API
- CORS
- Problem Details
- Rate limiting
- API versioning
- OpenAPI
- API endpoint discovery
- CORS configuration checker
- API error disclosure checker
- Rate-limit header checker
- API cache policy checker
- OpenAPI document checker
- Works in Postman, not browser
- 429 responses
- SaaS websites
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website