diff --git a/frontend/apply/src/app/apply/[id]/page.tsx b/frontend/apply/src/app/apply/[id]/page.tsx index 986829b..7141cd5 100644 --- a/frontend/apply/src/app/apply/[id]/page.tsx +++ b/frontend/apply/src/app/apply/[id]/page.tsx @@ -112,7 +112,10 @@ export default function ApplyPage() {

{t("applyPage.loginRequiredMessage")}

- + {t("applyPage.goToLogin")}
diff --git a/frontend/apply/src/app/login/page.tsx b/frontend/apply/src/app/login/page.tsx index 5fd910e..24c68f7 100644 --- a/frontend/apply/src/app/login/page.tsx +++ b/frontend/apply/src/app/login/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { useRouter } from "next/navigation"; +import { useRouter, useSearchParams } from "next/navigation"; import TextInput from "@/components/TextInput"; import Button from "@/components/Button"; import styles from "./login.module.css"; @@ -12,6 +12,8 @@ import "@/i18n/config"; export default function Login() { const { t } = useTranslation(); const router = useRouter(); + const searchParams = useSearchParams(); + const rawNext = searchParams.get("next"); const { isLoggedIn, loading } = useIsLoggedIn(); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); @@ -34,7 +36,25 @@ export default function Login() { if (response.status === 200) { window.dispatchEvent(new CustomEvent("logged-in")); - router.push("/"); + + const isSafeRedirect = (path: string | null) => { + if (!path) return false; + // Disallow absolute URLs or protocol markers + if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(path)) return false; + // Must be a normalized absolute path within this site + if (!path.startsWith("/")) return false; + // Prevent double slashes or attempts to break out + if (path.includes("//")) return false; + // Only allow redirects under /apply (application form pages) + return /^\/apply(\/.*)?$/.test(path); + }; + + const next = rawNext; + if (isSafeRedirect(next)) { + router.push(next as string); + } else { + router.push("/"); + } } else if (response.status === 401) { setError(t("loginPage.incorrectCredentials")); } else if (response.status === 403) {