No.
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); } |