Broken Object Property Level Authorization

Broken Object Property Level Authorization - Node.js/Express [GHSA-r4q5-vmmm-2653]

[Updated April 2026] Updated GHSA-r4q5-vmmm-2653

Overview

Broken Object Property Level Authorization (BOLA) in Node.js/Express can allow a user to access or modify resources that belong to another user by simply altering identifiers in a request. In real-world applications, such mistakes lead to data leakage, exposure of sensitive information, or unauthorized actions across accounts or tenants. This type of vulnerability frequently arises in multi-tenant SaaS or apps handling personal data, where the API relies on a user being authenticated but does not enforce ownership or permission at the resource level. If exploited, attackers can accumulate sensitive datasets, bypass access controls, and cause regulatory or reputational harm. Note: this guide presents general remediation guidance; no CVEs are referenced here because none were provided in this request.

Code Fix Example

Node.js (Express) API Security Remediation
// Vulnerable pattern (no ownership check)
const express = require('express');
const app = express();

const resources = [
  { _id: '1', owner: 'user1', data: 'secret1' },
  { _id: '2', owner: 'user2', data: 'secret2' }
];
const Resource = {
  findById: async (id) => resources.find(r => r._id === id),
  findOne: async (q) => resources.find(r => r._id === q._id && r.owner === q.owner)
};

app.get('/api/resource/vulnerable/:id', async (req, res) => {
  const id = req.params.id;
  const resource = await Resource.findById(id);
  if (!resource) return res.status(404).send('Not found');
  res.json(resource);
});

// Fixed pattern (enforces ownership)
function ensureAuthenticated(req, res, next) {
  req.user = { id: 'user1' }; // In production, verify JWT/session and set req.user
  next();
}

app.get('/api/resource/fixed/:id', ensureAuthenticated, async (req, res) => {
  const id = req.params.id;
  const resource = await Resource.findOne({ _id: id, owner: req.user.id });
  if (!resource) return res.status(404).send('Not found');
  res.json(resource);
});

app.listen(3000, () => console.log('Server running'));

CVE References

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