Broken Access Control and Missing Authorization
What Is This Vulnerability?
Broken access control occurs when an application does not properly enforce what authenticated users are allowed to do. Even with authentication in place, the absence of authorization checks means regular users can access admin functionality, modify other users' data, or perform actions beyond their intended role. This is consistently ranked among the top web application vulnerabilities.
Why It Happens
Authorization logic is often scattered across the codebase rather than centralized. Developers add authentication but forget per-endpoint authorization. Role checks are implemented inconsistently, with some routes checking permissions and others relying on UI hiding (not showing the button) as the only control. API endpoints are added without mirroring the restrictions present in the frontend.
Example Code
app.put("/api/users/:id/role", requireAuth, async (req, res) => {
const { role } = req.body;
await db.query(
"UPDATE users SET role = $1 WHERE id = $2",
[role, req.params.id]
);
res.json({ success: true });
});
app.get("/api/admin/analytics", requireAuth, async (req, res) => {
const data = await getAnalyticsData();
res.json(data);
});import { requireAuth, requireRole } from "@/middleware/auth";
app.put(
"/api/users/:id/role",
requireAuth,
requireRole("admin"),
async (req, res) => {
const { role } = req.body;
const allowedRoles = ["user", "editor"];
if (!allowedRoles.includes(role)) {
return res.status(400).json({ error: "Invalid role" });
}
await db.query(
"UPDATE users SET role = $1 WHERE id = $2",
[role, req.params.id]
);
res.json({ success: true });
},
);
app.get(
"/api/admin/analytics",
requireAuth,
requireRole("admin"),
async (req, res) => {
const data = await getAnalyticsData();
res.json(data);
},
);How Hackers Exploit It
Attackers authenticate as a regular user and then manually craft requests to admin-only endpoints. They modify request parameters (changing a user_id or role field) to escalate privileges or access restricted resources. Tools like Burp Suite make it trivial to replay and modify requests. If the API only hides features in the UI without server-side checks, any API call the admin can make is available to all users.
How to Fix It
Implement a centralized authorization middleware that checks roles and permissions on every request. Deny access by default and explicitly grant permissions per role. Never rely on client-side hiding as a security measure. Write authorization tests that verify regular users cannot access admin endpoints. Use a policy-based framework like CASL or a database-level row security policy.