API security: the OWASP API Security Top 10 and defences
In short: APIs expose business logic and data directly, so access-control mistakes are the biggest risk. The OWASP API Security Top 10 (2023) lists the most common failures, led by broken object level authorisation. Defend in layers: strong authentication, per-object and per-function checks, input validation, rate limits, inventory and monitoring.
Why APIs need their own security focus
A web page hides much of its logic behind buttons and forms. An API exposes that logic directly: every endpoint, parameter and ID is visible to anyone who looks at the traffic from a mobile app or browser. Attackers do not need clever exploits when they can simply change an ID in a URL and receive someone else’s data. That is why the OWASP (Open Worldwide Application Security Project) publishes a separate API Security Top 10. The current edition is from 2023.
The access-control risks
Three of the top five risks are about authorisation, which shows where real incidents come from.
- API1 Broken Object Level Authorisation (BOLA): the API checks that you are logged in, but not that the object you asked for belongs to you. Changing
/orders/1001to/orders/1002returns another customer’s order. Fix: check ownership or permission on every object, on the server, on every request. Random IDs (such as UUIDs) make guessing harder but are not a fix on their own. - API3 Broken Object Property Level Authorisation (BOPLA): the API returns or accepts fields it should not. A profile endpoint returns password hashes, or a user sends
"role": "admin"in an update and it is saved (mass assignment). Fix: explicit allow-lists of fields for output and input. - API5 Broken Function Level Authorisation (BFLA): a normal user can call admin functions, for example by switching GET to DELETE or guessing
/admin/paths. Fix: deny by default and check roles on every function.
@app.get("/api/v1/tickets/<int:ticket_id>")
@require_token(scope="tickets.read")
def get_ticket(ticket_id):
ticket = db.get_ticket(ticket_id)
if ticket is None or ticket.owner_id != current_user().id:
abort(404) # do not reveal that it exists
return {"id": ticket.id, "title": ticket.title, "status": ticket.status}
The other risks in brief
| Risk | What goes wrong | Key defence |
|---|---|---|
| API2 Broken Authentication | Weak tokens, no lockout, unsigned or unchecked JWTs | Standard OAuth 2.0/OIDC, MFA, strict token validation |
| API4 Unrestricted Resource Consumption | No limits on requests, page sizes or uploads | Rate limits, quotas, maximum sizes, timeouts |
| API6 Unrestricted Access to Sensitive Business Flows | Bots abuse a legitimate flow, such as bulk sign-ups | Flow-level limits, bot detection, step-up checks |
| API7 Server Side Request Forgery (SSRF) | API fetches a URL supplied by the user, reaching internal systems | Allow-list destinations, block internal and metadata addresses |
| API8 Security Misconfiguration | Verbose errors, open CORS, missing TLS, default settings | Hardened baselines, automated config checks |
| API9 Improper Inventory Management | Forgotten old versions and test endpoints left running | API inventory, retire old versions, documented owners |
| API10 Unsafe Consumption of APIs | Trusting data from third-party APIs without checks | Validate and limit what you accept from partners |
Building and testing defences
- Inventory: list every API, version, owner and data type. Unknown APIs cannot be protected.
- Gateway: put APIs behind an API gateway for TLS, authentication, rate limiting and logging. A WAF (Web Application Firewall) helps with generic attacks but cannot understand your object ownership rules.
- Authorisation in code: check object, property and function permissions in the service itself, with shared, tested helper functions.
- Validate input against a schema (type, length, range, allowed values) and return only the fields the caller needs.
- Test: include authorisation tests in CI (Continuous Integration), for example user A must get 404 or 403 for user B’s objects. Run authorised security testing before release.
- Monitor: log who called what, alert on spikes in 401, 403 and 404 responses, and watch for one client walking through sequential IDs.
Tip: security testing of an API you do not own is illegal in many countries without written permission. Practise on deliberately vulnerable lab applications in an isolated environment.
Practice
A user changes the account number in GET /api/accounts/5531 and sees another person’s balance. Which OWASP API risk is this?
Why can an API gateway not fully prevent BOLA?
What is mass assignment and which category covers it?
Key takeaways
- The OWASP API Security Top 10 (2023) is led by broken object level authorisation.
- Check permissions per object, per property and per function, on every request.
- Rate limits, size limits and timeouts stop resource exhaustion.
- Keep an API inventory and retire old versions and test endpoints.
- Gateways help, but access control must live in the application code.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.