Broken Access Control: Why It's the #1 OWASP Risk (With Real Exploits & Fixes)
Why Broken Access Control Is #1
Broken Access Control (A01:2021) took the top spot in the OWASP Top 10 in 2021 and has remained there through 2025. According to OWASP's data, 94% of applications tested had some form of broken access control, with a 3.81% incidence rate across 318,000+ CWEs mapped to this category.
What It Means: Access control enforces policy such that users cannot act outside their intended permissions. When it fails, attackers can view other users' data, modify records, escalate privileges, or perform administrative actions — all common paths to full system compromise.
Access Control Vulnerability Taxonomy
| Vulnerability Type | CWE | Description | CVSS Range |
|---|---|---|---|
| IDOR | CWE-639 | Accessing resources by manipulating identifiers | 5.3 - 8.6 |
| Privilege Escalation | CWE-269 | Gaining higher privileges than assigned | 7.5 - 9.8 |
| Forced Browsing | CWE-425 | Accessing unlinked pages/endpoints directly | 5.3 - 7.5 |
| CORS Misconfiguration | CWE-942 | Overly permissive cross-origin policies | 5.3 - 8.1 |
| JWT Manipulation | CWE-347 | Forging or tampering with auth tokens | 7.5 - 9.8 |
| Path Traversal | CWE-22 | Accessing files outside intended directory | 5.3 - 9.1 |
| Missing Function-Level Control | CWE-285 | API endpoints lacking authorization checks | 6.5 - 9.8 |
| Metadata Manipulation | CWE-639 | Tampering with hidden fields, cookies | 5.3 - 8.6 |
IDOR (Insecure Direct Object References)
The most common and most exploited access control vulnerability. IDOR occurs when an application exposes internal object references (IDs, filenames, database keys) and fails to verify that the requesting user owns or has access to the referenced object.
Real-World IDOR Exploits
1. US Department of Defense (HackerOne, 2020)
A researcher discovered that changing the user_id parameter on an internal DoD portal revealed service records, personal information, and documents for any military member over the past 70 years. Severity: Critical.
2. Uber (2019)
A bug allowed any driver to access trip receipts and personal details of any rider by iterating through trip IDs in the API endpoint /api/trips/{trip_id}/receipt.
Vulnerable IDOR Code
// VULNERABLE — No authorization check
app.get("/api/orders/:orderId", async (req, res) => {
const order = await Order.findById(req.params.orderId);
res.json(order); // Returns order regardless of who owns it
});
Secure IDOR Fix
// SECURE — Authorization check ensures ownership
app.get("/api/orders/:orderId", authenticate, async (req, res) => {
const order = await Order.findById(req.params.orderId);
if (!order) {
return res.status(404).json({ error: "Order not found" });
}
// Verify the authenticated user owns this order
if (order.userId.toString() !== req.user.id) {
return res.status(403).json({ error: "Access denied" });
}
res.json(order);
});
Advanced IDOR Prevention
- Use UUIDs instead of sequential IDs — Makes enumeration impractical
- Implement object-level authorization on every endpoint — Never trust the client
- Use indirect reference maps — Map session-specific tokens to real IDs server-side
- Rate limit API endpoints — Detect and block enumeration attempts
Privilege Escalation
Vertical Privilege Escalation
A regular user gains admin capabilities:
// VULNERABLE — Role check only on frontend
// Backend API has no role verification
app.delete("/api/admin/users/:userId", authenticate, async (req, res) => {
// Missing: if (req.user.role !== 'admin') return res.status(403)...
await User.findByIdAndDelete(req.params.userId);
res.json({ message: "User deleted" });
});
// SECURE — Server-side role enforcement
app.delete("/api/admin/users/:userId", authenticate, authorize("admin"), async (req, res) => {
await User.findByIdAndDelete(req.params.userId);
auditLog.record({
action: "USER_DELETED",
actor: req.user.id,
target: req.params.userId,
timestamp: new Date(),
});
res.json({ message: "User deleted" });
});
// Reusable authorization middleware
function authorize(...allowedRoles) {
return (req, res, next) => {
if (!allowedRoles.includes(req.user.role)) {
auditLog.record({
action: "UNAUTHORIZED_ACCESS_ATTEMPT",
actor: req.user.id,
endpoint: req.originalUrl,
timestamp: new Date(),
});
return res.status(403).json({ error: "Insufficient privileges" });
}
next();
};
}
Horizontal Privilege Escalation
A user accesses another user's data at the same privilege level — this is essentially IDOR applied to peer resources.
CORS Misconfigurations
The #1 CORS Mistake
// VULNERABLE — Reflects any origin (defeats same-origin policy entirely)
app.use(cors({
origin: (origin, callback) => callback(null, true), // allows ALL origins
credentials: true,
}));
Secure CORS Configuration
// SECURE — Explicit allowlist
const ALLOWED_ORIGINS = [
"https://securecodereviews.com",
"https://app.securecodereviews.com",
];
app.use(cors({
origin: (origin, callback) => {
if (!origin || ALLOWED_ORIGINS.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true,
methods: ["GET", "POST", "PUT", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization"],
}));
Access Control Architecture
Defense-in-Depth Model
Layer 1: API Gateway
├── Rate limiting
├── Authentication (JWT/OAuth validation)
└── Basic RBAC (admin vs user routes)
Layer 2: Service/Application
├── Object-level authorization (IDOR prevention)
├── Function-level authorization (role/permission checks)
├── Business logic authorization (ownership, team membership)
└── Input validation
Layer 3: Data
├── Row-level security (database policies)
├── Column-level encryption (sensitive fields)
└── Audit logging
Testing for Broken Access Control
| Test Type | Tools | What It Finds |
|---|---|---|
| Manual IDOR testing | Burp Suite, curl | Object-level access failures |
| Automated scanning | OWASP ZAP, Nuclei | Missing auth on endpoints |
| Fuzzing IDs | Custom scripts, Burp Intruder | Sequential ID enumeration |
| Role matrix testing | Manual / AuthMatrix Burp extension | Cross-role access violations |
| JWT testing | jwt.io, jwt_tool | Token manipulation, alg:none attack |
| CORS testing | curl, Burp | Overly permissive origin policies |
Further Reading
- OWASP Top 10 2025 — Full vulnerability framework
- OWASP Access Control Cheat Sheet — Implementation guidelines
- JWT Security Guide — Token security deep dive
- Secure API Design Patterns — API security architecture
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.