Harden auth, payments, and frontend against review findings.
Close exploitable gaps in booking/payment flows, enforce token versioning and account checks, gate sensitive payment data, and add middleware plus input validation across admin routes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -314,10 +314,11 @@ export const paymentOptionsApi = {
|
||||
body: JSON.stringify(data),
|
||||
}),
|
||||
|
||||
// Event-specific options (merged with global)
|
||||
getForEvent: (eventId: string) =>
|
||||
// Event-specific options (merged with global). Pass ticketId after booking to
|
||||
// retrieve bank/TPago credentials gated behind the booking capability token.
|
||||
getForEvent: (eventId: string, ticketId?: string) =>
|
||||
fetchApi<{ paymentOptions: PaymentOptionsConfig; hasOverrides: boolean }>(
|
||||
`/api/payment-options/event/${eventId}`
|
||||
`/api/payment-options/event/${eventId}${ticketId ? `?ticketId=${encodeURIComponent(ticketId)}` : ''}`
|
||||
),
|
||||
|
||||
// Event overrides (admin only)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Returns a safe internal redirect path, or the provided fallback.
|
||||
*
|
||||
* Only same-origin relative paths are allowed (must start with a single "/" and not
|
||||
* "//", which the browser treats as protocol-relative -> external). This prevents
|
||||
* open-redirect attacks via a `?redirect=` parameter.
|
||||
*/
|
||||
export function safeInternalPath(value: string | null | undefined, fallback: string = '/'): string {
|
||||
if (!value) return fallback;
|
||||
// Must be a relative path rooted at "/", but not "//" or "/\" (protocol-relative).
|
||||
if (!value.startsWith('/')) return fallback;
|
||||
if (value.startsWith('//') || value.startsWith('/\\')) return fallback;
|
||||
// Reject attempts to smuggle a scheme or control characters.
|
||||
if (/[\x00-\x1f]/.test(value) || value.includes('\\')) return fallback;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a URL is safe to use as an external navigation target:
|
||||
* an absolute https:// URL, or a same-origin relative path.
|
||||
*/
|
||||
export function isSafeExternalUrl(value: string | null | undefined): boolean {
|
||||
if (!value) return false;
|
||||
if (value.startsWith('/') && !value.startsWith('//') && !value.startsWith('/\\')) return true;
|
||||
try {
|
||||
const url = new URL(value);
|
||||
return url.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user