OWASP API Security Top 10 (2023) Explained: BOLA, Broken Auth, SSRF and Real API Attacks
On this page
OWASP API Security Top 10 Explained
If you are looking for a practical explanation of the OWASP API Security Top 10, focus on the few categories that show up repeatedly in real systems: BOLA, broken authentication, rate limiting failures, business logic abuse, shadow APIs, and SSRF. These are the issues that turn routine API mistakes into breach paths.
The OWASP API Security Project maintains a separate Top 10 list specifically for APIs, distinct from the web application OWASP Top 10. APIs have unique attack patterns that web-focused frameworks don't adequately address.
Why a Separate List? APIs expose application logic and sensitive data directly. Unlike web applications, APIs don't have a UI that limits what users can do — any client can send any request to any endpoint. This makes authorization, input validation, and rate limiting critical at the API layer.
The latest version (2023) was a complete overhaul from the 2019 edition:
| # | API Security Risk (2023) | Change from 2019 |
|---|---|---|
| API1 | Broken Object Level Authorization (BOLA) | Same (#1 both years) |
| API2 | Broken Authentication | Updated |
| API3 | Broken Object Property Level Authorization | New (merged mass assignment + excessive data exposure) |
| API4 | Unrestricted Resource Consumption | New (replaces Lack of Resources) |
| API5 | Broken Function Level Authorization | Same |
| API6 | Unrestricted Access to Sensitive Business Flows | New |
| API7 | Server-Side Request Forgery (SSRF) | New |
| API8 | Security Misconfiguration | Same |
| API9 | Improper Inventory Management | Updated |
| API10 | Unsafe Consumption of APIs | New |
API1: Broken Object Level Authorization (BOLA)
The #1 API vulnerability — also known as IDOR (Insecure Direct Object Reference) in web context. An attacker changes an object ID in a request to access another user's data.
Attack Scenario:
# Legitimate request
GET /api/v2/accounts/1001/transactions
Authorization: Bearer <user_1001_token>
# Attack — change account ID
GET /api/v2/accounts/1002/transactions
Authorization: Bearer <user_1001_token>
# Server returns user 1002's transactions — BOLA vulnerability!
Fix Pattern:
// Verify object ownership on EVERY request
async function getTransactions(req: Request) {
const accountId = req.params.accountId;
const userId = req.auth.userId;
// Check ownership BEFORE returning data
const account = await Account.findById(accountId);
if (!account || account.ownerId !== userId) {
return new Response("Not found", { status: 404 }); // 404, not 403
}
const transactions = await Transaction.find({ accountId });
return Response.json(transactions);
}
Best Practice: Return 404 (Not Found) instead of 403 (Forbidden) for unauthorized object access. A 403 confirms the object exists, enabling enumeration.
API2: Broken Authentication
API authentication failures include weak passwords, missing MFA, exposed credentials in URLs, and improper JWT validation.
Common JWT Mistakes:
// VULNERABLE — Not verifying JWT signature
const decoded = jwt.decode(token); // decode without verify!
const userId = decoded.userId;
// VULNERABLE — Algorithm confusion (accepts "none")
const decoded = jwt.verify(token, publicKey); // No algorithm restriction
// SECURE — Strict verification
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
algorithms: ["HS256"], // Explicitly allow only expected algorithm
issuer: "securecodereviews.com",
audience: "api.securecodereviews.com",
maxAge: "15m", // Reject tokens older than 15 minutes
});
API3: Broken Object Property Level Authorization
APIs that return more data than the client needs, or allow clients to modify properties they shouldn't.
Excessive Data Exposure:
// VULNERABLE — Returns entire user object (including sensitive fields)
app.get("/api/users/:id", auth, async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user); // Includes: password hash, SSN, internal notes, role!
});
// SECURE — Explicit field selection
app.get("/api/users/:id", auth, async (req, res) => {
const user = await User.findById(req.params.id)
.select("name email avatar createdAt"); // Only public fields
res.json(user);
});
Mass Assignment:
// VULNERABLE — Accepts any fields from request body
app.put("/api/users/:id", auth, async (req, res) => {
await User.findByIdAndUpdate(req.params.id, req.body); // Attacker sends { role: "admin" }!
});
// SECURE — Allowlist updateable fields
app.put("/api/users/:id", auth, async (req, res) => {
const allowedFields = ["name", "email", "avatar"];
const updates = {};
for (const field of allowedFields) {
if (req.body[field] !== undefined) updates[field] = req.body[field];
}
await User.findByIdAndUpdate(req.params.id, updates);
});
API4: Unrestricted Resource Consumption
APIs without proper rate limiting and resource constraints are vulnerable to DoS and financial abuse.
// Comprehensive rate limiting
import rateLimit from "express-rate-limit";
// Global rate limit
app.use(rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 1000, // 1000 requests per window
standardHeaders: true,
}));
// Sensitive endpoint rate limit
app.use("/api/auth/login", rateLimit({
windowMs: 15 * 60 * 1000,
max: 5, // 5 login attempts per 15 minutes
message: { error: "Too many login attempts. Try again later." },
}));
// Expensive operation rate limit
app.use("/api/reports/generate", rateLimit({
windowMs: 60 * 60 * 1000,
max: 10, // 10 report generations per hour
}));
API5: Broken Function Level Authorization
Regular users can access admin functions by simply calling admin endpoints.
API6: Unrestricted Access to Sensitive Business Flows
APIs that expose business logic without proper controls — e.g., automated ticket buying, coupon abuse, review manipulation.
Example Attack: An API for an e-commerce site allows adding items to cart and checking out. An attacker automates the entire flow to buy limited-edition items before legitimate customers.
Defenses: CAPTCHAs for sensitive flows, device fingerprinting, behavioral analysis, purchase velocity limits.
API7: Server-Side Request Forgery (SSRF)
APIs that fetch URLs provided by users can be tricked into accessing internal resources.
// VULNERABLE — Fetches any URL the user provides
app.post("/api/fetch-url", async (req, res) => {
const response = await fetch(req.body.url); // Can access internal services!
res.json(await response.json());
});
// Attacker sends: { "url": "http://169.254.169.254/latest/meta-data/iam/" }
// Gets AWS instance metadata and credentials!
API8: Security Misconfiguration
Missing CORS restrictions, verbose errors, unnecessary HTTP methods enabled, missing security headers.
API9: Improper Inventory Management
Organizations don't know all their APIs — shadow APIs, zombie APIs, and undocumented endpoints.
API10: Unsafe Consumption of APIs
When your API consumes third-party APIs without proper validation, you inherit their vulnerabilities.
API Security Testing Matrix
| Risk | Manual Testing | Automated Tool |
|---|---|---|
| BOLA | Swap object IDs between users | Burp Autorize extension |
| Broken Auth | Test JWT manipulation, expired tokens | jwt_tool, OWASP ZAP |
| Property Auth | Send unexpected fields in PUT/PATCH | Burp Intruder |
| Resource | Send oversized payloads, rapid requests | Artillery, k6 |
| Function Auth | Call admin endpoints as regular user | AuthMatrix (Burp) |
| Business Logic | Automate purchase/reservation flows | Custom scripts |
| SSRF | Send internal URLs (169.254.x, localhost) | SSRFmap |
OWASP API Security Top 10 FAQ
What is the most common OWASP API Security Top 10 issue?
Broken Object Level Authorization, or BOLA, remains the most common and most damaging API risk because it turns ordinary API requests into unauthorized data access with only small changes to object IDs or resource references.
Is the OWASP API Security Top 10 only for public APIs?
No. Internal APIs, partner APIs, mobile backends, and service-to-service endpoints can all suffer from the same authorization, authentication, SSRF, and inventory-management failures.
How should teams use the OWASP API Security Top 10 in practice?
Use it as a testing and review framework. Map existing endpoints to the top risks, review auth and authorization flows first, then test for resource abuse, API inventory gaps, and unsafe downstream integrations.
Further Reading
- OWASP API Security Project — Official documentation
- API Security Trends 2026 — Current threat landscape
- Shadow APIs Guide — Finding hidden APIs
- Broken Access Control Deep Dive — Authorization patterns
Published by SecureCodeReviews
This article is part of our original AI security and cybersecurity content library. We show publish and update dates, keep company and policy pages public, and update important guidance when material changes affect readers.
Planning an AI feature launch or security review?
We assess prompt injection paths, data leakage, tool use, access control, and unsafe AI workflows before they become production problems.
Advertisement
Free Security Tools
Try our tools now
Expert Services
Get professional help
OWASP Top 10
Learn the top risks
Related Articles
Secure API Design Patterns: A Developer's Guide
Learn the essential security patterns every API developer should implement, from authentication to rate limiting.
JWT Security: Vulnerabilities, Best Practices & Implementation Guide
Comprehensive JWT security guide covering token anatomy, common vulnerabilities, RS256 vs HS256, refresh tokens, and secure implementation patterns.
Securing Generative AI APIs: MCP Security & Shadow AI Risks in 2026
Model Context Protocol (MCP) is the emerging standard for connecting AI to tools and data. But MCP servers, shadow AI usage, and AI supply chain attacks introduce critical risks. Learn how to secure generative AI APIs.