Broken Object Level Authorization

Broken Object Level Authorization in Node.js (Express) [CVE-2026-39381]

[Updated Apr 2026] Updated CVE-2026-39381

Overview

Broken Object Level Authorization (BOLA) in web APIs enables horizontal privilege escalation, where a user can access or modify another user's resources by manipulating object identifiers. In real-world Node.js/Express apps, this often happens when endpoints enforce authentication but skip authorization checks on per-resource operations such as GET /resources/:id, PUT /resources/:id, or DELETE /resources/:id. In Node.js (Express), a common pattern is to fetch a resource by its ID and return it directly if found. If you rely solely on a session or token check (you are authenticated) without validating ownership, an attacker who knows or guesses an ID can access sensitive data, change data, or delete resources that belong to others. Impact can include data exposure, account compromise, fraud, or operational disruption across multi-tenant apps, e-commerce portals, or collaboration tools. The vulnerability scales with public listing endpoints or patterns that trust IDs from clients. No CVEs provided in this prompt; this guide focuses on principled, defense-in-depth fixes and test strategies to prevent object-level authorization flaws in Express apps.

Code Fix Example

Node.js (Express) API Security Remediation
// Vulnerable pattern (no ownership check)\n// Requires auth middleware to set req.user (e.g., from JWT)\n\nconst express = require('express');\nconst app = express();\nconst resources = [ { id: '1', ownerId: 'u1', data: '...' }, { id: '2', ownerId: 'u2', data: '...' } ];\n\napp.get('/resources/:id', (req, res) => {\n  const resource = resources.find(r => r.id === req.params.id);\n  if (!resource) return res.status(404).send('Not found');\n  // Vulnerable: no authorization check\n  res.json(resource);\n});\n\n// Fixed pattern: enforce object-level authorization\napp.get('/resources/:id', (req, res) => {\n  const resource = resources.find(r => r.id === req.params.id);\n  if (!resource) return res.status(404).send('Not found');\n  if (!req.user) return res.status(401).send('Unauthorized');\n  if (resource.ownerId !== req.user.id) return res.status(403).send('Forbidden');\n  res.json(resource);\n});\n\nmodule.exports = app;

CVE References

Choose which optional cookies to allow. You can change this any time.