Summary
In apps/web/src/app/api/store/invoices/[id]/route.ts, the GET endpoint queries invoices by ID without filtering by user_id in the database query (line 48). Ownership is checked after retrieval (line 52), which leaks whether an invoice exists based on different HTTP status codes (404 vs 403).
Impact
An authenticated user can enumerate valid invoice IDs by observing 404 vs 403 responses. Additionally, the error message on line 50 leaks raw database error details.
Fix
Add .eq('user_id', auth.userId) to the query so non-owned invoices return 404 (indistinguishable from non-existent). Replace error.message with a generic error.
Summary
In
apps/web/src/app/api/store/invoices/[id]/route.ts, the GET endpoint queries invoices by ID without filtering byuser_idin the database query (line 48). Ownership is checked after retrieval (line 52), which leaks whether an invoice exists based on different HTTP status codes (404 vs 403).Impact
An authenticated user can enumerate valid invoice IDs by observing 404 vs 403 responses. Additionally, the error message on line 50 leaks raw database error details.
Fix
Add
.eq('user_id', auth.userId)to the query so non-owned invoices return 404 (indistinguishable from non-existent). Replaceerror.messagewith a generic error.