Authentication answers "who are you." Authorization answers "are you allowed." The bugs in this family are the ones where the first check passed but the second one was skipped, weak, or applied to the wrong subject.
The most common shape is IDOR — Insecure Direct Object Reference. GET /api/orders/123 returns order 123 to anyone who's logged in, instead of only to the user who owns it. The route handler authenticated the request, then loaded the row, then returned it without checking that the row belongs to the requesting user.
Defenses: scope every database query by the user (WHERE user_id = $current_user), apply policies at the route layer with a framework like CASL or oso, and use opaque or signed identifiers in URLs so attackers can't enumerate them. The first one is the most reliable — a query that physically can't return rows the user doesn't own can't IDOR.
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 — the canonical industry classification for this bug class. Useful when filing tickets, writing security policies, or arguing with a static analyzer.