OWASP API Security Top 10
APIs power mobile apps, single-page websites, partner integrations, and internal services. They expose data and actions directly, with no friendly page in between. OWASP publishes a separate Top 10 list for APIs because their risks differ from classic web page risks. The 2023 edition is the current list at the time of writing.
The Restaurant Kitchen Window Comparison
A website resembles a dining room with a menu, a waiter, and rules. An API resembles a kitchen service window where staff pass plates straight to anyone who asks. Without a careful check at the window, the wrong person receives the wrong plate.
Where APIs Sit
Mobile app ──┐
Web app ───┼──→ API ──→ Business logic ──→ Database
Partner ───┘
Every arrow needs identity, permission, and limit checks
The 2023 List
| Code | Risk | Plain Meaning |
|---|---|---|
| API1 | Broken Object Level Authorization | Users read or change records that belong to others by changing an ID |
| API2 | Broken Authentication | Weak login or token handling lets attackers act as users |
| API3 | Broken Object Property Level Authorization | Users see or edit fields they should not, such as a role field |
| API4 | Unrestricted Resource Consumption | No limits let clients drain processing power, memory, or money |
| API5 | Broken Function Level Authorization | Normal users call administrator functions |
| API6 | Unrestricted Access to Sensitive Business Flows | Bots abuse purchase, signup, or booking flows at scale |
| API7 | Server Side Request Forgery | The API fetches addresses supplied by the user and reaches internal systems |
| API8 | Security Misconfiguration | Open settings, verbose errors, or missing headers |
| API9 | Improper Inventory Management | Old, forgotten, or undocumented API versions stay online |
| API10 | Unsafe Consumption of APIs | The app trusts data from third-party APIs without checks |
The Most Common Flaw: Object Level Authorization
Consider an API address that returns an invoice:
GET /api/invoices/1001A user who owns invoice 1001 changes the number to 1002 and receives a stranger's invoice because the server never checks ownership. The fix lives in the server code: confirm that the logged-in user owns the requested record on every request.
Request: GET /api/invoices/1002 (user A)
|
↓
Does invoice 1002 belong to user A?
|-- yes → return data
|-- no → return 403 Forbidden
Property Level Problems
Mass assignment happens when an API binds every field from the request to a stored object. A user who adds "role": "admin" to a profile update may promote themselves. Accept only an allowlist of editable fields and return only the fields the client needs.
Defense Checklist
- Authorize every request at the object, property, and function level.
- Use unpredictable identifiers, but never rely on secrecy of IDs alone.
- Apply rate limits, size limits, and timeouts.
- Keep a complete inventory of API versions and retire old ones.
- Validate and limit data received from third-party APIs.
- Return generic error messages and log details privately.
- Describe the API with a specification file and test against it automatically.
Key Takeaways
- APIs expose logic and data directly, so authorization matters most.
- The API list focuses on object, property, and function permissions.
- Limits and inventory control prevent abuse and forgotten entry points.
- Server-side checks on every request close the majority of the gaps.
