Fix open redirect in Stripe customer portal returnUrl (FRE-5399)
- Add isValidReturnUrl validation at route level for fast rejection - Add defense-in-depth validation in BillingService.createCustomerPortalSession - Fix isValidReturnUrl bug: origin comparison was never reached due to incorrect protocol check, allowing substring attacks (e.g., app.shieldai.com.evil.com) - Export isValidReturnUrl from shared-billing package index - Add unit tests for all attack vectors Files changed: - packages/api/src/routes/subscription.routes.ts - packages/shared-billing/src/services/billing.service.ts - packages/shared-billing/src/config/billing.config.ts - packages/shared-billing/src/index.ts - packages/shared-billing/src/__tests__/billing.config.test.ts
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import Stripe from 'stripe';
|
||||
import { loadBillingConfig, SubscriptionTier } from '../config/billing.config';
|
||||
import { loadBillingConfig, SubscriptionTier, isValidReturnUrl } from '../config/billing.config';
|
||||
import { RedisService } from '@shieldsai/shared-notifications';
|
||||
import type { Subscription, SubscriptionCreateSchema, SubscriptionUpdateSchema } from '../models/subscription.model';
|
||||
|
||||
@@ -168,6 +168,9 @@ export class BillingService {
|
||||
customerId: string,
|
||||
returnUrl: string
|
||||
): Promise<Stripe.BillingPortal.Session> {
|
||||
if (!isValidReturnUrl(returnUrl)) {
|
||||
throw new Error(`Invalid return URL: ${returnUrl}`);
|
||||
}
|
||||
return await stripe.billingPortal.sessions.create({
|
||||
customer: customerId,
|
||||
return_url: returnUrl,
|
||||
|
||||
Reference in New Issue
Block a user