M_04/ A01:2021 — Broken Access Control

Broken Access Control

Tamper with identifiers in the URL bar, body, or token. The server's authorization check happens in plain English on the right.

1.0 Address Bar
Presets
2.0 Server-Side Handler
200 OK
// VULNERABLE — no authorization check
app.get('/api/users/:id/profile', (req, res) => {
  const user = db.users.findById(req.params.id);
  res.json(user);
});
// ❌ missing: ownership check (req.params.id !== req.user.id)
Response body
{ "id": 1002, "email":"victim@x.com", "ssn":"***-**-1234" }
Secure handler
if (req.params.id !== req.user.id && !req.user.isAdmin)
  return res.sendStatus(403);
const user = db.users.findById(req.params.id);
3.0 Intelligence

What just happened

The server returns 200 OK but should have returned 403 Forbidden. The handler uses the user-supplied identifier directly without verifying ownership or role.

Logical flow

  • 01Attacker observes the URL/ID format from a legitimate request.
  • 02Substitutes an identifier they should not have access to.
  • 03Server fetches the object without checking ownership.
  • 04Object returned — privilege boundary crossed.
Risk
Critical
OWASP
A01
↳ What the developer intended
Only the owner (or an admin) can fetch a given object.
↳ What the runtime actually executes
Object is fetched by ID and returned with no further checks.
Any user who knows the ID can read it.
Attack flow