diff --git a/packages/api/src/routes/subscription.routes.ts b/packages/api/src/routes/subscription.routes.ts index 58a866e..193b302 100644 --- a/packages/api/src/routes/subscription.routes.ts +++ b/packages/api/src/routes/subscription.routes.ts @@ -341,6 +341,16 @@ export async function subscriptionRoutes(fastify: FastifyInstance) { }); } + // Verify the customer belongs to the authenticated user (IDOR prevention) + try { + await billingService.verifyCustomerOwnership(customerId, authReq.user.id); + } catch { + return reply.status(403).send({ + error: 'Forbidden', + message: 'You do not have access to this customer', + }); + } + try { const invoices = await billingService.getInvoiceHistory(customerId); diff --git a/packages/shared-billing/src/services/billing.service.ts b/packages/shared-billing/src/services/billing.service.ts index 7eb93d7..5d218ec 100644 --- a/packages/shared-billing/src/services/billing.service.ts +++ b/packages/shared-billing/src/services/billing.service.ts @@ -37,7 +37,7 @@ export class BillingService { } } - private async verifyCustomerOwnership( + async verifyCustomerOwnership( customerId: string, userId: string ): Promise {