Skip to main content

API3:2023 Broken Object Property Level Authorization

Mass assignment: the handler binds the request body straight into a model object, so a client can write privileged fields (for example is_admin: true) the API never meant to accept.

What Vulkro detects​

Unbounded body-to-model assignments such as Model(**request.json), Object.assign(user, req.body) and setattr(model, k, v) for k, v in body.items(), with equivalents across frameworks. Findings name the bound model and the missing allowlist.

Non-compliant code​

// Express: unbounded body bind
app.post('/users/:id', async (req, res) => {
const updates = req.body; // accepts `is_admin: true` if the model has the field
await User.update(req.params.id, updates);
res.sendStatus(204);
});

Compliant code​

// Express: allowlist of writable fields
const ALLOWED = ['display_name', 'avatar_url'];
app.post('/users/:id', async (req, res) => {
const updates = Object.fromEntries(
Object.entries(req.body).filter(([k]) => ALLOWED.includes(k))
);
await User.update(req.params.id, updates);
res.sendStatus(204);
});

References​

See also: Confidence model.


This page is generated by vulkro rules export <out-dir> from Vulkro's built-in detector catalogue. Edits made by hand are overwritten on the next regeneration.