Why this matters

The bug. ASP.NET Core's middleware has already validated the auth scheme (JWT, cookie auth, whatever) by the time the handler runs. The verified principal is on HttpContext.User. Reading Request.Cookies["user_id"] instead grabs a *separate*, unauthenticated value that the client controls — so users can act as anyone by changing one cookie.

The fix. Read from User.FindFirst("sub")?.Value (the JWT subject claim) or User.Identity?.Name. Both are populated only by the authentication middleware using the verified token.

Why this slips past review. It looks like 'just reading a cookie' until you remember the trust boundary. ASP.NET Core's docs reinforce the pattern via [Authorize] + claim reads — this code skipped the second half.

Review heuristic

Every endpoint that accepts an id parameter needs a sentence in the diff or the spec answering: who is allowed to access objects with this id? If the answer is "any authenticated user," that's an IDOR. If the answer is "the owner," verify the query enforces it at the database layer.

External reference: CWE-639: Authorization Bypass Through User-Controlled Key.

CWE-639; OWASP A01:2021.