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) {