OWASP API Security Top 10 (2023): Every Vulnerability Explained With Real Attacks
What Is the OWASP API Security Top 10?
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 |
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
Advertisement
Free Security Tools
Try our tools now
Expert Services
Get professional help
OWASP Top 10
Learn the top risks
Related Articles
OWASP Top 10 2025: What's Changed and How to Prepare
A comprehensive breakdown of the latest OWASP Top 10 vulnerabilities and actionable steps to secure your applications against them.
Secure API Design Patterns: A Developer's Guide
Learn the essential security patterns every API developer should implement, from authentication to rate limiting.
The Ultimate Secure Code Review Checklist for 2025
A comprehensive, actionable checklist for conducting secure code reviews. Covers input validation, authentication, authorization, cryptography, error handling, and CI/CD integration with real-world examples.