ASP.NET Core code review: fixing an AI-generated GetOrder endpoint (IDOR, DTOs, 404)

ASP.NET Core Interview Q&A November 13, 2026 csharp

No.

csharp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// ======================================================================
// Q: Claude Code generated this endpoint. Would you merge it?
//
// No. The problems:
// - IDOR / BOLA: there is no [Authorize] and nothing checks that the order
//   belongs to the user's tenant or customer. Change the id and you see other
//   companies' orders, which is critical in B2B.
// - Data exposure: it returns the EF entity directly. The whole Customer comes
//   along (e.g. billing details, credit limit) and there is a risk of circular
//   references.
// - Null handling: it returns 200 with null instead of 404.
// - CancellationToken and AsNoTracking() are missing.
// Return 404 rather than 403, so an attacker does not learn that the id exists.
// ======================================================================

// AI-generated endpoint under review
[HttpGet("api/orders/{id}")]
public async Task<IActionResult> GetOrder(int id)
{
    var order = await _db.Orders
        .Include(o => o.Customer)
        .Include(o => o.Lines)
        .FirstOrDefaultAsync(o => o.Id == id);

    return Ok(order);
}

// Fixed version: [Authorize], ownership filter, DTO projection, 404
[Authorize]
[HttpGet("api/orders/{id:int}")]
public async Task<ActionResult<OrderDto>> GetOrder(int id, CancellationToken ct)
{
    var customerId = User.GetCustomerId(); // from claims, NEVER from the request

    var order = await _db.Orders
        .AsNoTracking()
        .Where(o => o.Id == id && o.CustomerId == customerId)
        .Select(o => new OrderDto(
            o.Id, o.OrderNumber, o.Status, o.TotalNet,
            o.Lines.Select(l => new OrderLineDto(l.Sku, l.Quantity, l.UnitPrice)).ToList()))
        .FirstOrDefaultAsync(ct);

    return order is null ? NotFound() : Ok(order);
}