Broken access control (IDOR)
Changing an id in the URL should never show someone else’s data. The fix is one ownership check on the server.
Watch it animatedStep through it, with the running line highlighted. Free with an account.The idea
An insecure direct object reference happens when the server uses an id from the request without checking that the current user may access that object. It is the most common item in OWASP’s Broken Access Control category (A01).
Code
// Vulnerable: trusts the id from the URL
app.MapGet("/api/orders/{id}", (int id, Db db) =>
db.Orders.Find(id));
// Fixed: the order must belong to the signed-in user
app.MapGet("/api/orders/{id}", (int id, Db db, ClaimsPrincipal me) =>
{
var order = db.Orders.Find(id);
if (order is null || order.UserId != me.UserId())
return Results.NotFound();
return Results.Ok(order);
});Tips
- Check ownership or permission on every object access, on the server.
- Unguessable ids (UUIDs) help, but they are not access control.
- Returning 404 instead of 403 avoids confirming that the object exists.
In the .NET library
Resource-based authorisation in ASP.NET Core (IAuthorizationService with the object) keeps these checks consistent.