To secure an API endpoint, decide for every route who may call it, on which objects, how often and with what input. The OWASP API Security Top 10 (2023) puts broken object level authorization first because most breaches come from endpoints that authenticate callers but never check what they may touch.
Why are endpoints different from web pages?
OWASP notes that APIs tend to expose more endpoints than traditional web applications, which makes up to date documentation and inventory important. Each route is a small door, and the server usually keeps no memory of the client's state. It relies on parameters, such as object IDs, that the client sends to decide what to return.
That design is why the most common flaw is easy to find. An attacker logs in as themselves, changes an ID in a request and sees whether someone else's record comes back.
What are the ten risks?
The 2023 list, in OWASP's order: broken object level authorization, broken authentication, broken object property level authorization, unrestricted resource consumption, broken function level authorization, unrestricted access to sensitive business flows, server side request forgery, security misconfiguration, improper inventory management, and unsafe consumption of APIs.
You do not need all ten memorised. Treat them as ten questions to ask of each route.
How do you check authorization on a route?
OWASP's guidance for the first risk is direct: every API endpoint that receives an ID of an object and performs any action on it should implement object level authorization checks, validating that the logged in user may perform that action on that object. Compare the user in the session to the owner of the record, in code, on every call.
Property level checks come next. A user may be allowed to read their own profile but not the field that stores an internal risk score, and to update their name but not their role. OWASP merged the older excessive data exposure and mass assignment issues into this one. Return only the fields the caller needs and accept only the fields you expect.
Function level checks cover administrative routes. If an ordinary user can call a delete or export route by guessing its path, the access policy is not enforced where it matters.
What about volume and abuse?
Every request consumes bandwidth, CPU, memory and storage, and some consume paid services such as SMS or email. OWASP warns that unrestricted consumption can cause denial of service or higher costs. Set rate limits per caller, cap page sizes and payload sizes, and put timeouts on expensive operations.
Business flow abuse is subtler. A ticket purchase or comment route can work exactly as coded and still hurt the business when a script calls it a million times. Decide what normal use looks like for each flow.
A constructed example
A food delivery service has a route to fetch an order by number. The route checks that the caller has a valid token. It does not check that the order belongs to the caller. Order numbers are sequential.
A tester signs up, places one order, then asks for the numbers just before and after. Both return other customers' names and addresses. The fix is a single line comparing the order's customer ID to the token's subject, plus a switch to unpredictable identifiers as defence in depth. The unpredictable ID does not replace the check; it only makes guessing harder.
What about calls your API makes?
Two items on the list face outward. Server side request forgery happens when an API fetches a remote resource using a user supplied URL without validating it, which can reach internal services even behind a firewall. Unsafe consumption of APIs means trusting data from a third party API more than user input. Validate both.
How do you keep the inventory honest?
Generate your route list from the code or the gateway, not from a wiki page. Mark each route with an owner, an auth requirement and a data classification. Retire old versions and remove debug routes. Safeguard's dynamic application testing and the ability to find API endpoints in JavaScript can help surface routes nobody documented, and its SAST can flag missing authorization checks in code. Treat their output as leads to confirm.
How to check or apply this
- Generate a list of every route and method from code or the gateway.
- For each route, record who may call it and which objects they may touch.
- Add automated tests that call each route as user A against user B's objects.
- Return and accept only explicit field lists.
- Add rate limits, size caps and timeouts per caller and per route.
- Validate any URL your API fetches and any data from third party APIs.
- Retire old versions and debug routes, and review the inventory every release.
Quick check
Is an API gateway enough?
A gateway can enforce authentication, rate limits and schema checks. It rarely knows which user owns which object, so object level checks still belong in the service.
Do unpredictable IDs fix broken object level authorization?
No. They make guessing harder but do not replace the ownership check.
Sources
Last reviewed: 18 October 2026.