The owasp api security top 10 exists because the original web Top 10 stopped describing the bugs production teams were actually shipping. When applications became collections of microservices behind API gateways, when mobile clients started talking directly to backends, and when B2B integrations replaced server-rendered HTML, the dominant vulnerability classes shifted — and the old categories no longer fit. The first OWASP API Security Top 10 was published in 2019; the revision shipped in 2023. This guide walks the 2023 list end to end — what each category means, what it looks like in real backend code, the architectural fixes, and the cross-cutting playbook. Depth on individual categories lives in spoke posts: SSRF, security misconfiguration, authentication failures, and broken access control are linked inline where they map to API1 through API10.
Why API Security Got Its Own Top 10
The original OWASP Top 10 dates to 2003 and through every revision until 2017 it was effectively a list of web application bugs — server-rendered HTML, session cookies, form posts, classic MVC controllers. By the late 2010s the architecture had shifted: the browser was no longer the primary client but one of many, the endpoints themselves had become the application — REST APIs, GraphQL, gRPC, webhooks — and the rendering had moved to the client. This was a structural reorganization of where the security boundaries lived.
The web Top 10 missed the shift in specific ways. CSRF is largely a web-form attack; APIs authenticating via bearer tokens do not have a classic CSRF surface. XSS is a browser-side concern; a JSON-only API never rendering HTML has no XSS surface. Conversely, the patterns that dominate API breaches — predictable object IDs that bypass authorization, business workflows abused through automation, third-party API responses trusted without validation, internal endpoints exposed through gateway misconfiguration — were not first-class categories on the web list. The OWASP API Security Project published its first Top 10 in 2019 to address that gap and revised it in 2023. The drivers for the revision were microservices architectures becoming standard (production systems now exposing hundreds of internal APIs, many with weaker controls than the public tier), mobile backends multiplying, B2B integrations becoming routine, and breach data confirming that the largest incidents shared patterns the 2019 list did not name well.
What Changed From 2019 to 2023
The 2023 revision kept Broken Object Level Authorization at #1 — every signal from breach data, pentest findings, and incident response confirmed that BOLA remained the single most common high-severity API bug. The Optus 2022 breach, which exposed personal data of approximately 10 million Australian customers, was a textbook BOLA: predictable customer IDs in the API URL, no server-side check that the requesting user owned the requested ID, and an attacker able to enumerate records by incrementing the integer. The Peloton 2021 incident, which exposed user data including age, gender, and workout statistics, was the same pattern. T-Mobile's 2023 API breach, which affected roughly 37 million customers, traced to misuse of an API endpoint that authorized callers per session but did not enforce object-level scope on the data each session could read. BOLA was, and is, the most consequential category, and the 2023 list left it at #1 to reflect that.
The authentication categories were consolidated. The 2019 list had Broken User Authentication at #2 and several adjacent issues — credential stuffing patterns, weak token handling, missing MFA — distributed across other categories. The 2023 list merged the authentication concerns into a single Broken Authentication category at API2, broadened to include API key management, JWT verification weaknesses, and OAuth flow misconfigurations. The merge reflected that, in practice, an authentication failure in an API surface is rarely about one mechanism failing in isolation — it is about the combined system of token issuance, validation, and credential lifecycle producing an exploitable seam.
Mass Assignment, which had been API6 on the 2019 list, was renamed and broadened to Broken Object Property Level Authorization (BOPLA). The new category covers both the classic mass-assignment pattern (a request body with extra fields like is_admin that the controller blindly assigns to the model) and the symmetric problem of excessive data exposure (a response that returns the entire model including sensitive fields like password_hash). The renaming captured the underlying issue: the application's authorization model has gaps at the property level, where individual fields are not subject to the same checks as the object itself.
A new category was introduced for unrestricted access to sensitive business flows. The 2019 list framed rate limiting as denial-of-service; the 2023 list keeps that framing for the resource-consumption case (now API4) and adds a separate API6 for business-flow abuse — workflows like account creation, ticket purchase, or gift-card redemption that get exhausted through automation even when no individual request is abusive. SSRF was elevated to its own category at API7, reflecting both the increased prominence of cloud architectures (where SSRF can pivot to metadata services) and its visibility in API breach reports — depth on this lives in the SSRF deep-dive. Improper Assets Management became Improper Inventory Management (API9), broadening from "shadow APIs" to the full inventory-discipline problem. Insufficient Logging & Monitoring was dropped on the reasoning that it is cross-cutting. Unsafe Consumption of APIs (API10) was added to address the third-party trust problem — backends that treat external API responses as trusted input.
API1:2023 — Broken Object Level Authorization (BOLA)
BOLA is the API-layer manifestation of broken access control, and the single most consequential API vulnerability class in 2026 — it has held the #1 position since the first API Top 10 in 2019. The pattern: an API endpoint accepts an object identifier in the URL, query string, or body; the endpoint authenticates the caller (verifies the JWT or session token); but it does not check that the authenticated caller is authorized to access the specific object identified by that ID. The result is broken access control at the object level, where any authenticated user can access any object by knowing or guessing its ID.
The Optus breach is the canonical real-world example. The endpoint /api/customers/[id] required authentication but not that the authenticated user be the customer in question. Customer IDs were small, effectively sequential integers. An attacker who registered, obtained a token, and incremented the ID read every customer record in the system. The scale — 10 million records — was a direct consequence of the integer-ID design combined with the missing authorization check.
The vulnerable pattern in Express:
// Vulnerable: authenticated but no object-scope check
app.get('/api/orders/:id', requireAuth, async (req, res) => {
const order = await Order.findById(req.params.id)
if (!order) return res.status(404).send('Not found')
res.json(order)
})The fix is an explicit object-level authorization check at every endpoint that accepts an object identifier:
// Fixed: verify the authenticated user owns the object
app.get('/api/orders/:id', requireAuth, async (req, res) => {
const order = await Order.findById(req.params.id)
if (!order) return res.status(404).send('Not found')
if (order.userId !== req.user.id && !req.user.isAdmin) {
return res.status(403).send('Forbidden')
}
res.json(order)
})The architectural fix scales beyond per-endpoint checks. The data access layer takes the authenticated session as input and constructs queries that automatically include the appropriate authorization filters — a pattern related to the disciplines covered in broken access control. Tools like Pundit, CanCanCan, Casbin, and OpenFGA encode authorization policies declaratively and apply them at every query boundary, eliminating the per-endpoint opportunity for omission. UUIDs help reduce the enumeration surface but are not a substitute for authorization — a leaked UUID is still a valid identifier.
API2:2023 — Broken Authentication
Broken authentication on APIs is broader than the equivalent web category. APIs typically authenticate via tokens — bearer tokens, JWTs, API keys — issued by a separate authentication service. The vulnerabilities concentrate in the issuance, validation, lifecycle, and revocation of those tokens. The 2022 Twitter API leak that exposed 5.4 million accounts is a relevant example: an API endpoint accepted an email address or phone number and returned the associated Twitter account ID, effectively offering account-enumeration as a service to anyone with a valid API token. The endpoint required authentication but not authorization-aware rate limiting, and the attack was performed by automated scripts that called it millions of times over weeks.
The common API authentication failures cluster into a small set of patterns. JWT signature verification skipped or done with the wrong algorithm — the classic alg: none attack, or the HMAC-with-public-key attack where a token signed with the public RSA key is accepted because the verification code does not pin the algorithm. API keys treated as identifiers rather than secrets — leaked into source repositories, into client-side mobile apps, into URL query strings logged by upstream proxies. OAuth flows with insecure redirect handling, missing PKCE, or implicit-flow tokens that bypass the authorization-code exchange. Session tokens that never expire or expire only on logout, leaving leaked tokens valid indefinitely.
The architectural fix is to centralize token issuance and validation in a single, well-tested authentication service, and to never reimplement the verification logic per-service. Every backend service validates tokens using the same library, with the same algorithm pinning, audience and issuer checks, and expiration enforcement. API keys, where used, are scoped, rotated, and never embedded in client code. Spoke depth on this category lives in the authentication failures developer guide.
API3:2023 — Broken Object Property Level Authorization (BOPLA)
BOPLA covers two symmetric problems. On the request side: a client sends a request body with fields the endpoint should not accept — is_admin: true, account_balance: 999999, verified: true — and the controller blindly assigns the request body to the model. This mass assignment vulnerability is the canonical BOPLA bug on the request side. On the response side: an endpoint returns an object that includes fields the client should not see — password hashes, internal IDs, audit fields, moderation flags. This is excessive data exposure.
The vulnerable mass-assignment pattern in Rails:
# Vulnerable: every attribute in params is accepted
def update
@user = User.find(current_user.id)
@user.update(params[:user])
render json: @user
endAn attacker submits {"user": {"name": "alice", "is_admin": true}} and the update assigns both fields. The fix in Rails is strong parameters — an explicit allowlist of fields the controller will accept:
# Fixed: explicit allowlist of permitted fields
def update
@user = User.find(current_user.id)
@user.update(user_params)
render json: @user, only: [:id, :name, :email]
end
private
def user_params
params.require(:user).permit(:name, :email)
endThe same discipline applies in every framework — Express with Joi/Zod/ajv, Spring Boot DTOs, Django REST Framework serializers — because the mass assignment vulnerability pattern shows up anywhere a controller binds the raw request body to a persistence model without an explicit allowlist. The response-side fix is symmetric: every endpoint specifies the fields it returns, either through serializer/DTO classes or through query projections that select only the intended fields. The pattern eliminates the class of bugs where a developer adds a new field to the database and it becomes visible to API consumers because no one updated the response shape.
API4:2023 — Unrestricted Resource Consumption
This category covers attacks that exhaust the API's underlying resources — CPU, memory, database connections, third-party API quotas, cloud-cost budgets — through requests that are individually valid but collectively destructive. It is broader than "rate limiting": a single request that triggers a 10-minute database query, that fetches 100,000 records in one page, or that triggers a third-party API call billed at $0.10 — each can produce resource exhaustion without sending many requests.
The mitigations stack across layers. At the gateway, request-rate throttling per token, per IP, and per endpoint shapes traffic before it reaches the application. At the application, query limits enforce maximum page sizes, result counts, query depth (for GraphQL), and upload sizes. At the infrastructure, connection pools have caps and timeouts; database queries have statement timeouts; third-party clients have circuit breakers and budget-aware quotas.
An example Kong rate-limiting plugin configuration that throttles per-consumer:
plugins:
- name: rate-limiting
config:
minute: 60
hour: 1000
policy: redis
redis_host: redis.internal
fault_tolerant: true
hide_client_headers: false
limit_by: consumerThe configuration limits each authenticated consumer to 60 requests per minute and 1,000 per hour. The same shape applies in AWS API Gateway throttling configuration, in Nginx limit_req directives, and in Envoy rate-limit filters. The discipline is to apply the throttle at the gateway, not in the application — gateway-layer enforcement protects the application from absorbing the request cost in the first place.
API5:2023 — Broken Function Level Authorization (BFLA)
BFLA is BOLA's twin and another of the API-specific broken access control patterns. Where BOLA is a missing authorization check on an object identifier, BFLA is a missing authorization check on a function — typically an admin endpoint that requires authentication but does not require admin privileges. The classic pattern: the application has /api/users/:id for normal user access and /api/admin/users/:id for admin access; the admin endpoint requires authentication but the authorization check is missing or incorrect. Any authenticated user — not just admins — can call the admin endpoint and get admin-level functionality.
BFLA is particularly common when an application uses a single backend but multiple client tiers (customer-facing mobile, employee back-office, admin console). Pentest findings repeatedly surface admin endpoints that work fine when called with a customer's token, because the authorization check was implemented at the UI layer (the customer app simply does not show the admin button) rather than at the API layer. The fix is centralized, role-based, function-level authorization — every endpoint declares the role or permission it requires; Spring Security, NestJS guards, Express middleware, and Rails before-actions all support the pattern. The discipline is to decline to ship any endpoint without an explicit authorization decorator. This connects to the broader architecture covered in broken access control.
API6:2023 — Unrestricted Access to Sensitive Business Flows
This is the new category for 2023, addressing attacks that exhaust or abuse business workflows even when no individual request is abusive. The pattern: a workflow has business value at human pace (account creation, gift-card redemption, ticket purchase, password reset) and that value collapses or inverts when automated. Bots create thousands of fake accounts to farm sign-up bonuses; scripts brute-force gift-card numbers to find valid balances; password-reset endpoints get abused to mass-deliver phishing emails. The 2022 Twitter API leak fits this category in part — the abuse was a workflow (look up account by email or phone) being used at machine scale to enumerate the user base.
The mitigations are different from rate limiting. Pure request-rate throttling does not stop a determined bot operator with a residential proxy network. The controls that work are CAPTCHAs and challenge-response gates on high-stakes flows, behavioral analytics, device fingerprinting, account-age and account-trust signals (a 5-minute-old account cannot redeem a gift card), and human-in-the-loop review for high-value actions. The architecture is to layer enough friction that abuse becomes economically unattractive.
API7:2023 — Server-Side Request Forgery (SSRF)
SSRF is the vulnerability class where an API endpoint takes a URL or hostname from the request, fetches that URL server-side, and returns the response (or uses the response in subsequent processing). When the URL is unvalidated, an attacker can target internal endpoints — cloud metadata services, internal admin APIs, localhost services, link-local addresses — and read responses the attacker should not have access to. The cloud-metadata variant is particularly damaging: AWS, GCP, and Azure all expose instance metadata at well-known internal IPs, and SSRF that reaches that metadata can return short-lived credentials with broad cloud privileges.
The Capital One 2019 breach is the most-cited SSRF incident: an SSRF in a web application reached AWS instance metadata, exfiltrated IAM credentials, and used those credentials to read S3 buckets containing 100 million customer records. The pattern repeats in API breach reports — webhook senders, image fetchers, URL previewers, RSS aggregators, and OAuth callback handlers are common SSRF surfaces.
The mitigations include allowlist validation of URL hosts, IP-address validation that resolves DNS first and rejects private/loopback ranges, network-level egress controls that prevent the application from reaching internal endpoints in the first place, and in cloud environments the use of IMDSv2 (which requires session-token authentication and significantly raises the bar on SSRF-to-credentials attacks). Depth on this category lives in the SSRF developer guide.
API8:2023 — Security Misconfiguration
The misconfiguration category is the API mirror of the web equivalent. The patterns are different in detail but identical in shape: defaults that should not be defaults (debug mode in production, verbose error messages, default credentials on management interfaces), settings that should be configured but are not (CORS allowing any origin, TLS not enforced on some routes, security headers missing on API responses), and exposed surfaces that should not be exposed (Swagger/OpenAPI documentation in production, GraphQL introspection enabled in production, debug endpoints reachable from the public internet).
API gateway misconfiguration is a particularly common source of incidents. A gateway rule that was meant to route only public endpoints accidentally routes internal admin endpoints; a gateway with authentication-required mode for one route and authentication-optional for another lets attackers find the unprotected variant; a CORS configuration that was correct for the web app accidentally allows arbitrary origins through a wildcard. The fix is misconfiguration-as-code — gateway configuration in version control, code review on every change, automated configuration tests that assert the expected security properties, and periodic external scans that verify the production state matches the intended state. Depth on this category lives in the security misconfiguration deep-dive.
API9:2023 — Improper Inventory Management
You cannot secure what you do not know exists. The improper-inventory-management category covers the discipline of knowing what APIs you run — public APIs, internal APIs, deprecated APIs that are still online, beta APIs that escaped to production, partner-only APIs that became internet-facing, mobile-client APIs that are no longer used by any current app version. In production systems with hundreds of services and years of history, the inventory drift is significant; pentests routinely discover endpoints that no current employee remembers deploying, running on infrastructure no one has the credentials to log into.
The fix is inventory discipline as a first-class engineering practice. Every API has an OpenAPI or GraphQL schema in the repository. Every deployment registers itself with a service catalog. Every public DNS entry resolving to an HTTP service is reviewed periodically. Deprecated APIs have a documented timeline and an enforced end-of-life date. External attack-surface management tools (RiskIQ, Censys, dedicated API discovery tools) provide an outside-in view that catches what the inside-out catalog misses.
An inventory-friendly OpenAPI definition pattern looks like this:
openapi: 3.0.3
info:
title: Customer API
version: 2.4.0
x-internal-team: payments-team
x-data-classification: pii
servers:
- url: https://api.example.com/v2
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
paths:
/customers/{id}:
get:
summary: Get customer by ID
x-required-scope: customers:read
x-data-classification: pii
parameters:
- in: path
name: id
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'Every endpoint declares its required scope, its data classification, and its owning team. The schema is the source of truth for the gateway, the documentation, the SDKs, and the inventory tooling. Schema-driven inventory makes "what APIs do we run, who owns them, what data do they touch?" a query rather than a research project.
API10:2023 — Unsafe Consumption of APIs
API10 addresses the third-party trust problem. Modern applications consume external APIs constantly — payment processors, identity providers, geocoding, email, AI/ML APIs, CRM, analytics SDKs. The dominant assumption is that a third-party response can be trusted because the third party is reputable and the connection is over TLS. The 2023 list challenges that: third-party APIs can be compromised, their responses can be malicious, and treating their data as trusted input can produce vulnerabilities in the consuming application.
The patterns include responses containing XSS payloads when rendered to a web client; responses with SSRF-style URLs when the consumer follows them; bloated payloads designed to crash the parser or exhaust memory; unexpected types that exploit weak deserialization. The supply-chain dimension matters: a third-party SDK trusted at adoption time can be compromised later. The mitigations apply the same disciplines to third-party data as to any other untrusted input — validate the response schema against an explicit definition, treat third-party URLs as SSRF candidates, pin and audit SDK versions. The principle is "the network boundary is the trust boundary," regardless of the third party's reputation.
The Cross-Cutting Mitigation Playbook
The ten categories above converge on a small set of cross-cutting mitigations that, applied consistently, eliminate the majority of API security risk. None are individually sufficient; the pattern that produces durable security is the layered application of all of them.
Centralized authorization. Every authorization decision — object-level, function-level, property-level — runs through a single, audited authorization service or library. Tools like OpenFGA, Cedar, Casbin, Pundit, and CanCanCan implement this pattern at varying levels of sophistication. The centralization eliminates the "every endpoint reimplements the auth check" failure mode that produces BOLA, BFLA, and BOPLA findings in volume. Combined with authorization-aware data access layers, it produces queries that are authorization-scoped by construction rather than by per-endpoint discipline.
Schema-driven validation. Every API endpoint has an explicit schema for its request and response. The schema is enforced at the framework level — incoming requests are validated against the schema and rejected on mismatch; outgoing responses are projected through the schema and stripped of fields outside it. The schema also drives gateway routing, documentation, SDK generation, and inventory. The single source of truth eliminates the documentation drift, mass-assignment surface, and excessive-data-exposure surface in one move.
Rate limiting at the gateway. Throttling, quota enforcement, and abuse detection live at the gateway layer rather than in the application code. The gateway sees all traffic; the application sees only what the gateway forwards. Enforcing rate limits at the gateway protects every backend service consistently, applies the controls before the request reaches expensive code paths, and produces uniform telemetry for abuse detection.
API inventory discipline. Every API is registered, documented, owned, classified, and tracked. Every public DNS entry resolving to an HTTP service has a corresponding entry in the catalog. Every deprecated API has a deprecation schedule and an end-of-life date that is enforced. External attack-surface scanning verifies the production state. The investment is ongoing; the return is that the inventory drift that produces "we found a 2017 admin endpoint still running on staging" stops being a routine pentest finding.
Gateway-level authentication and contract testing. Token validation and signature verification happen at the gateway; applications receive requests with verified identity claims rather than raw tokens. Every API has a contract — the OpenAPI or GraphQL schema — and consumer-driven contract testing (Pact, Spring Cloud Contract) verifies that producers and consumers stay aligned, with schema-change reviews catching the case where a new field is added to a response without considering whether it should be exposed.
Runtime API observability. Production traffic is observed continuously — request rates, response codes, payload patterns, anomalies in caller behavior. API security platforms (Salt Security, Noname Security, 42Crunch, Wallarm) provide the runtime view that catches abuse the static controls miss. The observability is the safety net that detects BOLA exploitation in progress, business-flow abuse at scale, and credential-stuffing attempts that slip past gateway controls.
Developer training on API-specific patterns. The web Top 10 and the API Top 10 are different lists for a reason; teams that have internalized the web list still need to learn the API patterns. Training that walks BOLA, BFLA, BOPLA, business-flow abuse, and SSRF in the context of REST and GraphQL — and that uses real incidents like Optus, Peloton, T-Mobile, and Twitter as case studies — produces fluency that scanner findings alone do not.
BOLA Is Still #1. Train Your Backend Team Like It Is.
An API gateway with rate limits and a WAF will not stop the BOLA bug your team is about to ship next sprint. Schema validation will not catch the missing object-scope check. SAST tools find a fraction of API authorization findings, and only after the code is written. SecureCodingHub builds the API-specific fluency — BOLA recognition, BFLA discipline, BOPLA prevention, business-flow threat modeling — that turns the API Top 10 from a checklist into a way backend engineers think about every new endpoint. If your team's last API pentest produced more authorization findings than you would like to admit, we would be glad to show you a different shape of training.
See the PlatformClosing: The API Top 10 Is the Architecture, Not the Checklist
The OWASP API Security Top 10 is often read as a checklist — ten boxes to tick, ten findings to clear. The framing produces incremental progress and persistent recurrence. The teams that have substantially closed their API security surface in 2026 read the list differently: as a description of the architectural patterns that, applied consistently across every service, make the categories structurally hard to introduce. Centralized authorization makes BOLA hard. Schema-driven validation makes BOPLA hard. Gateway-level rate limiting makes resource-exhaustion hard. API inventory discipline makes shadow APIs hard. The architecture is the answer; the checklist is the symptom. The web Top 10's 2025 revision shows the same pattern of evolution in the web context — categories merge, new ones are introduced, names get refined as the field's understanding deepens.
For backend engineers and API platform leads, the practical takeaway is that the API Top 10 is best read as a roadmap for the platform team's investment, not as a list of bugs the application security team will find for you. The platform decisions set the floor on how secure any individual service can be; above that floor, per-service work is real but bounded; below that floor, no amount of per-service diligence makes the system secure. Ship the platform pieces, train the team on the patterns, and the API Top 10 becomes a list you read to confirm what the architecture already prevents.