In this lesson, you will learn how to enforce resource-level authorization to ensure users can only access data they are explicitly permitted to view or modify.
The Problem: Insecure Direct Object References (IDOR)
An IDOR vulnerability occurs when an application exposes a reference to an internal object—such as a database primary key—in a URL or API parameter without checking if the requester actually owns that resource.
Imagine a simple endpoint in your C# API:
GET /api/orders/{orderId}
If your code simply retrieves the order by orderId and returns it, any authenticated user could guess the ID of another user's order and successfully retrieve sensitive information. This is a failure in resource-level authorization.
The Fix: Validate Ownership
To prevent this, you must always verify that the resource being requested belongs to the identity currently authenticated in the ClaimsPrincipal.
Here is a common pattern to secure this in a C# controller:
[HttpGet("{orderId}")]
public async Task<IActionResult> GetOrder(int orderId)
{
var order = await _dbContext.Orders.FindAsync(orderId);
// Identity check: Does the order belong to the current user?
var currentUserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (order == null || order.UserId != currentUserId)
{
return NotFound(); // Or Forbid() to explicitly deny access
}
return Ok(order);
}
Why This Matters
In this example, simply verifying that the user is "logged in" is insufficient. Even though the user is authenticated, they are not authorized to see someone else’s data. By comparing the order.UserId property against the ClaimTypes.NameIdentifier extracted from the secure, server-side identity context (the JWT or session cookie), you bridge the gap between "who is the user" and "what can this user touch."
Always treat identifiers coming from the client as untrusted input. Before performing any data operation, the application must perform a "ownership check" to confirm the resource is linked to the requesting user’s identity.
Key Takeaway: Never rely on client-provided IDs alone; always validate that the authenticated user has explicit ownership of the specific resource being requested.