diff --git a/packages/hydrogen-remix/src/routing/redirect.ts b/packages/hydrogen-remix/src/routing/redirect.ts index 2a1d09238c..29a80c4585 100644 --- a/packages/hydrogen-remix/src/routing/redirect.ts +++ b/packages/hydrogen-remix/src/routing/redirect.ts @@ -1,3 +1,4 @@ +import {redirect} from '@remix-run/oxygen'; import type {HydrogenContext} from '@shopify/hydrogen'; export async function notFoundMaybeRedirect( @@ -23,10 +24,33 @@ export async function notFoundMaybeRedirect( }, }); } else { + const redirectPath = new URLSearchParams(search).get('redirect_to'); + + if (isLocalPath(redirectPath)) { + return redirect(redirectPath!); + } + return new Response('Not found', {status: 404}); } } +function isLocalPath(url: string | null) { + if (!url) return false; + + try { + // We don't want to redirect cross domain, + // doing so could create fishing vulnerability + // If `new URL()` succeeds, it's a fully qualified + // url which is cross domain. If it fails, it's just + // a path, which will be the current domain. + new URL(url); + } catch (e) { + return true; + } + + return false; +} + const REDIRECT_QUERY = `#graphql query redirects($url:String) { urlRedirects(first:1, query:$url) {