diff --git a/apps/console/src/pages/iam/auth/sign-in/PasswordSignInPage.tsx b/apps/console/src/pages/iam/auth/sign-in/PasswordSignInPage.tsx index 0736f845c..ee561f996 100644 --- a/apps/console/src/pages/iam/auth/sign-in/PasswordSignInPage.tsx +++ b/apps/console/src/pages/iam/auth/sign-in/PasswordSignInPage.tsx @@ -36,6 +36,20 @@ export default function PasswordSignInPage() { if (!emailValue || !passwordValue) return; + const continueUrlParam = searchParams.get("continue"); + let safeContinueUrl: string; + if (continueUrlParam) { + let continueUrl: URL; + try { + continueUrl = new URL(continueUrlParam, window.location.origin); + } catch { + continueUrl = new URL(window.location.origin); + } + safeContinueUrl = window.location.origin + continueUrl.pathname + continueUrl.search; + } else { + safeContinueUrl = window.location.origin; + } + signIn({ variables: { input: { @@ -59,7 +73,7 @@ export default function PasswordSignInPage() { return; } - window.location.href = searchParams.get("continue") ?? window.location.origin; + window.location.href = safeContinueUrl; }, onError: (e) => { toast({ diff --git a/apps/console/src/pages/iam/organizations/AssumePage.tsx b/apps/console/src/pages/iam/organizations/AssumePage.tsx index 35e772116..7ae837a85 100644 --- a/apps/console/src/pages/iam/organizations/AssumePage.tsx +++ b/apps/console/src/pages/iam/organizations/AssumePage.tsx @@ -38,18 +38,25 @@ function AssumePageInner() { const [assumeOrganizationSession] = useMutation(assumeMutation); - const continueUrl = searchParams.get("continue") ?? new URL(`/organizations/${organizationId}`, window.location.origin).toString(); + const continueUrlParam = searchParams.get("continue"); + let safeContinueUrl: string; + if (continueUrlParam) { + const continueUrl = new URL(continueUrlParam); + safeContinueUrl = window.location.origin + continueUrl.pathname + continueUrl.search; + } else { + safeContinueUrl = window.location.origin + `/organizations/${organizationId}`; + } useEffect(() => { assumeOrganizationSession({ variables: { - input: { organizationId, continue: continueUrl }, + input: { organizationId, continue: safeContinueUrl }, }, onError: (error) => { if (error instanceof UnAuthenticatedError) { const search = new URLSearchParams([ ["organization-id", organizationId], - ["continue", continueUrl], + ["continue", safeContinueUrl], ]); void navigate({ pathname: "/auth/login", search: "?" + search.toString() }); @@ -68,7 +75,7 @@ function AssumePageInner() { switch (result.__typename) { case "PasswordRequired": search.set("organization-id", organizationId); - search.set("continue", continueUrl); + search.set("continue", safeContinueUrl); void navigate({ pathname: "/auth/password-login", search: "?" + search.toString() }); break; @@ -79,11 +86,11 @@ function AssumePageInner() { window.location.href = samlSSOLoginURL.toString(); break; default: - window.location.href = continueUrl; + window.location.href = safeContinueUrl; } }, }); - }, [organizationId, navigate, assumeOrganizationSession, continueUrl, searchParams]); + }, [organizationId, navigate, assumeOrganizationSession, safeContinueUrl, searchParams]); return (