Overview
Broken Object Level Authorization (OWA) defects occur when APIs expose references to internal objects (like user records, orders, or files) and rely on client-supplied identifiers for access decisions. In real-world apps, an attacker might iteratively change an ID in the URL or request body to view or modify another user's data, orders, or resources. If exploited, this can lead to data leakage, account takeover, or unauthorized operations across tenants.
In Node.js with Express, this class of vulnerability often arises when route handlers fetch a resource by id without verifying that the authenticated user owns or is permitted to access it. Because Express leaves many object references in the request path ("/objects/:id") or in query parameters, an attacker can craft requests to read, update, or delete objects belonging to others. Attackers may maintain JWTs or sessions but still rely on missing or mistaken authorization checks.
To remediate, enforce explicit access controls at the resource level, ideally with centralized middleware or ABAC/RBAC patterns; ensure that a resource is loaded in a way that the current user is validated against ownership or permissions before any action; avoid returning objects solely because an ID was supplied; prefer endpoints that expose the current user's data (e.g., /me) and perform server-side checks regardless of what the client sends.
Code Fix Example
Node.js (Express) API Security Remediation
// Vulnerable pattern
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
const user = db.findUserById(userId);
res.json(user);
});
// Fixed pattern
app.get('/users/:id', authenticate, (req, res) => {
const userId = req.params.id;
const resource = db.findUserById(userId);
// Deny if requester is not the owner or an admin
const isOwner = String(req.user.id) === String(resource.id);
const isAdmin = req.user && req.user.role === 'admin';
if (!isOwner && !isAdmin) {
return res.status(403).json({ error: 'Forbidden' });
}
res.json(resource);
});