OWASP API Security Top 10 Explained
Every serious web application is an API now. The frontend talks to the backend through JSON endpoints, mobile apps do the same, and so does every script, bot, and scraper on the internet. APIs are also the least-patched surface in most architectures: they expose business logic directly, they lack the guardrails that forms and server-rendered pages used to have, and they are the number one way attackers reach data they were never meant to see.
The OWASP API Security Top 10 2023 is the consensus list of the most common and most damaging API security risks. It is not a theoretical document; every entry describes an attack that has been used in the wild against real products. This guide walks through all ten risks with concrete examples, so you can map each one to your own endpoints. Keep the OWASP API Top 10 reference open while you read, then audit your APIs against it.
1. Broken Object Level Authorization (BOLA)
BOLA is the single most common API security risk, and it is usually a one-line bug. It happens when an API trusts the object ID in the request without checking whether the caller is allowed to touch that object. GET /api/users/12345 returns user 12345 to anyone who asks, because the endpoint never verifies that the requester is user 12345 or has permission to view them.
The fix is not complex, it just has to happen on every single object access. Compare the object’s owner against the authenticated caller before returning anything:
app.get('/api/orders/:id', (req, res) => {
const order = await db.getOrder(req.params.id)
if (order.userId !== req.user.id) {
return res.status(403).json({ error: 'forbidden' })
}
res.json(order)
})
If even one endpoint forgets the check, the whole API is vulnerable. Authorization logic must live in the endpoint layer, not in the frontend, because a crafted HTTP request bypasses the UI entirely.
2. Broken Authentication
Broken authentication is any flaw in how the API proves who you are: predictable tokens, tokens that never expire, session IDs in URLs, missing brute-force protection on login endpoints, or an endpoint that accepts a leaked token from a revoked session. Because APIs are called by machines, a single leaked credential gives an attacker scripted access to the full account.
The baseline controls are: short-lived access tokens with refresh tokens, lockout or rate limiting on authentication endpoints, rotation of any credential that appears in a log, and strict validation on password reset and MFA endpoints.
3. Broken Object Property Level Authorization
This risk is about fields, not objects. The API returns the object correctly authorized, but it exposes or accepts properties it should not. GET /api/users/me returns isAdmin to every caller, or PATCH /api/users/me lets a user flip isAdmin to true because the update handler copies every field from the request body.
The fix is an explicit allowlist of properties each endpoint may return or accept. Never do Object.assign(user, req.body); copy only the fields the role is allowed to change, and serialize only the fields the client is allowed to see.
4. Unrestricted Resource Consumption
An API endpoint that performs expensive work without limits is a self-DoS. Paging with an unbounded limit parameter, unbounded pagination loops, costly list endpoints, and API calls without rate limits all let one client starve the service for everyone else.
Set hard caps on page sizes and request sizes, add rate limiting per API key and per IP, and put timeouts on expensive operations. Reject or truncate oversized input before processing it, not after.
5. Broken Function Level Authorization
Where BOLA is about objects, this is about functions: a normal user calling an endpoint that only admins should reach. The endpoint works correctly for admins, but the authorization check is only hidden in the UI, or the endpoint has no role check at all. GET /api/admin/users answers happily when called with a regular user token.
Every endpoint needs an explicit authorization check that maps to a role or permission, decided server-side. Never rely on the frontend hiding a button.
6. Unrestricted Access to Sensitive Business Flows
Some endpoints are not broken but are still dangerous. An API that lets anyone place an order, redeem a voucher, or submit a review is fine — until a script automates it a thousand times per minute. This risk is abuse of legitimate functionality: scalper bots, coupon stuffing, and fake signups.
Detect the pattern rather than the request: rate limits keyed to suspicious behavior, device and velocity heuristics, and blocklists for known bot traffic. The endpoint is correct; the volume is the attack.
7. Server-Side Request Forgery (SSRF)
SSRF happens when an API fetches a URL the attacker supplies. A feature that imports a profile image from image_url will happily fetch http://169.254.169.254/latest/meta-data/ (the cloud metadata service) if nothing blocks it. Attackers use SSRF to reach internal services, cloud credentials, and services that were never meant to be internet-facing.
Validate the scheme and host against an allowlist, resolve and verify the final IP against private ranges, and route outbound fetches through a restricted proxy.
8. Security Misconfiguration
The boring risks are the ones that actually bite: CORS set to *, debug endpoints left enabled, verbose error messages leaking stack traces and SQL, default credentials, and missing security headers. These are configuration, not code, so they never show up in code review.
Tighten CORS to explicit allowed origins, disable debug modes in production, strip internal details from error responses, and apply the standard security headers to every API response.
9. Improper Inventory Management
Shadow APIs are the danger here. A deprecated v1 endpoint stays live after the app moves to v2, an old staging environment is still reachable from the internet, or a debug route lives next to the production route. Attackers find these unpatched, forgotten endpoints and pivot through them.
Maintain an inventory of every host and endpoint, retire old versions on a hard schedule, and restrict environments by network and authentication rather than trusting obscurity.
10. Unsafe Consumption of Third-Party APIs
Your API is only as safe as the APIs it calls. If your code passes raw user input into a third-party API call, or trusts a third-party response without validation, you inherit that provider’s bugs and data handling. A malicious response can inject data or cause harmful behavior downstream.
Validate and sanitize everything sent to and received from third-party APIs, authenticate every outbound call, and treat third-party responses as untrusted input.
Next steps
Audit your endpoints against all ten entries in the OWASP API Top 10 reference, and start with BOLA: grep every object-access endpoint and confirm it checks ownership before it returns data.
Try it now: open the owasp api top 10 tool — free, runs entirely in your browser, nothing is uploaded.