Files
timmal/app/utils/validateRedirect.ts

38 lines
1.3 KiB
TypeScript

/**
* Validates a redirect URL to prevent open redirect vulnerabilities.
*
* Only allows same-origin redirects (paths starting with `/` but not `//`).
* External URLs, protocol-relative URLs, and invalid input are rejected.
*
* @param redirect - The redirect URL to validate (typically from query parameters)
* @param fallback - The fallback path to use if validation fails (default: '/dashboard')
* @returns A validated same-origin path or the fallback path
*
* @example
* ```typescript
* // Valid same-origin paths
* validateRedirect('/dashboard') // returns '/dashboard'
* validateRedirect('/projects/123') // returns '/projects/123'
*
* // Rejected external URLs (returns fallback)
* validateRedirect('https://evil.com') // returns '/dashboard'
* validateRedirect('//evil.com') // returns '/dashboard'
*
* // Invalid input (returns fallback)
* validateRedirect(null) // returns '/dashboard'
* validateRedirect(undefined) // returns '/dashboard'
*
* // Custom fallback
* validateRedirect('https://evil.com', '/login') // returns '/login'
* ```
*/
export const validateRedirect = (redirect: string | unknown, fallback = '/dashboard'): string => {
if (typeof redirect !== 'string') {
return fallback;
}
if (redirect.startsWith('/') && !redirect.startsWith('//')) {
return redirect;
}
return fallback;
}