OWASP
Broken Access Control
IDOR
OWASP
Privilege Escalation
+3 more

Broken Access Control: Why It's the #1 OWASP Risk (With Real Exploits & Fixes)

SCR Security Research Team
February 11, 2026
19 min read
Share

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 TypeCWEDescriptionCVSS Range
IDORCWE-639Accessing resources by manipulating identifiers5.3 - 8.6
Privilege EscalationCWE-269Gaining higher privileges than assigned7.5 - 9.8
Forced BrowsingCWE-425Accessing unlinked pages/endpoints directly5.3 - 7.5
CORS MisconfigurationCWE-942Overly permissive cross-origin policies5.3 - 8.1
JWT ManipulationCWE-347Forging or tampering with auth tokens7.5 - 9.8
Path TraversalCWE-22Accessing files outside intended directory5.3 - 9.1
Missing Function-Level ControlCWE-285API endpoints lacking authorization checks6.5 - 9.8
Metadata ManipulationCWE-639Tampering with hidden fields, cookies5.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 TypeToolsWhat It Finds
Manual IDOR testingBurp Suite, curlObject-level access failures
Automated scanningOWASP ZAP, NucleiMissing auth on endpoints
Fuzzing IDsCustom scripts, Burp IntruderSequential ID enumeration
Role matrix testingManual / AuthMatrix Burp extensionCross-role access violations
JWT testingjwt.io, jwt_toolToken manipulation, alg:none attack
CORS testingcurl, BurpOverly permissive origin policies

Further Reading

Advertisement