Overview
Broken Object Property Level Authorization in Node.js (Express) can allow attackers to read or modify fields on a resource that should be restricted, even when authentication and basic resource-level checks exist. This misalignment between authentication and granular permission checks translates into real-world impact such as privilege escalation, exposure of sensitive attributes (for example ownerId, isAdmin, or configuration flags), and unintended actions that compromise data integrity or confidentiality. Without proper property-level guards, attackers may exploit endpoints that blindly apply client-supplied data to domain models, undermining the principle of least privilege.
Code Fix Example
Node.js (Express) API Security Remediation
VULNERABLE:\n// Vulnerable pattern: directly applying client input to the resource\napp.patch('/api/resources/:id', async (req, res) => {\n const resource = await Resource.findById(req.params.id);\n if(!resource) return res.status(404).send();\n Object.assign(resource, req.body); // no property-level checks\n await resource.save();\n res.json(resource);\n});\n\nFIXED:\n// Fixed: whitelist fields and enforce authorization\napp.patch('/api/resources/:id', async (req, res) => {\n const allowedUpdates = ['name','description','config'];\n const updates = Object.keys(req.body);\n const isAllowed = updates.every(u => allowedUpdates.includes(u));\n if(!isAllowed) return res.status(400).send({ error: 'Invalid updates' });\n const resource = await Resource.findById(req.params.id);\n if(!resource) return res.status(404).send();\n // authorization check: only owner or admin can modify\n if(resource.ownerId.toString() !== req.user.id && req.user.role !== 'admin') {\n return res.status(403).send({ error: 'Not authorized' });\n }\n updates.forEach(u => resource[u] = req.body[u]);\n await resource.save();\n res.json(resource);\n});