From 384fd19203b63eeb4b952f83a9e1eaab1b19b90d Mon Sep 17 00:00:00 2001 From: Elias Schneider Date: Fri, 5 Apr 2024 12:00:41 +0200 Subject: [PATCH] fix: redirect vulnerability on error, sign in and totp page --- frontend/src/components/auth/SignInForm.tsx | 3 ++- frontend/src/components/auth/TotpForm.tsx | 13 +++++++------ frontend/src/pages/error.tsx | 5 ++++- frontend/src/utils/router.util.ts | 7 +++++++ 4 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 frontend/src/utils/router.util.ts diff --git a/frontend/src/components/auth/SignInForm.tsx b/frontend/src/components/auth/SignInForm.tsx index e5bd96b..7696066 100644 --- a/frontend/src/components/auth/SignInForm.tsx +++ b/frontend/src/components/auth/SignInForm.tsx @@ -25,6 +25,7 @@ import useTranslate from "../../hooks/useTranslate.hook"; import authService from "../../services/auth.service"; import { getOAuthIcon, getOAuthUrl } from "../../utils/oauth.util"; import toast from "../../utils/toast.util"; +import { safeRedirectPath } from "../../utils/router.util"; const useStyles = createStyles((theme) => ({ or: { @@ -98,7 +99,7 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => { ); } else { await refreshUser(); - router.replace(redirectPath); + router.replace(safeRedirectPath(redirectPath)); } }) .catch(toast.axiosError); diff --git a/frontend/src/components/auth/TotpForm.tsx b/frontend/src/components/auth/TotpForm.tsx index 7fdf2ed..2fea6ca 100644 --- a/frontend/src/components/auth/TotpForm.tsx +++ b/frontend/src/components/auth/TotpForm.tsx @@ -6,15 +6,16 @@ import { PinInput, Title, } from "@mantine/core"; +import { useForm, yupResolver } from "@mantine/form"; +import { useRouter } from "next/router"; +import { useState } from "react"; import { FormattedMessage } from "react-intl"; import * as yup from "yup"; import useTranslate from "../../hooks/useTranslate.hook"; -import { useForm, yupResolver } from "@mantine/form"; -import { useState } from "react"; -import authService from "../../services/auth.service"; -import toast from "../../utils/toast.util"; -import { useRouter } from "next/router"; import useUser from "../../hooks/user.hook"; +import authService from "../../services/auth.service"; +import { safeRedirectPath } from "../../utils/router.util"; +import toast from "../../utils/toast.util"; function TotpForm({ redirectPath }: { redirectPath: string }) { const t = useTranslate(); @@ -46,7 +47,7 @@ function TotpForm({ redirectPath }: { redirectPath: string }) { router.query.loginToken as string, ); await refreshUser(); - await router.replace(redirectPath); + await router.replace(safeRedirectPath(redirectPath)); } catch (e) { toast.axiosError(e); form.setFieldError("code", "error"); diff --git a/frontend/src/pages/error.tsx b/frontend/src/pages/error.tsx index 9919a9a..57402cd 100644 --- a/frontend/src/pages/error.tsx +++ b/frontend/src/pages/error.tsx @@ -4,6 +4,7 @@ import Meta from "../components/Meta"; import useTranslate from "../hooks/useTranslate.hook"; import { useRouter } from "next/router"; import { FormattedMessage } from "react-intl"; +import { safeRedirectPath } from "../utils/router.util"; const useStyle = createStyles({ title: { @@ -39,7 +40,9 @@ export default function Error() { diff --git a/frontend/src/utils/router.util.ts b/frontend/src/utils/router.util.ts new file mode 100644 index 0000000..8387334 --- /dev/null +++ b/frontend/src/utils/router.util.ts @@ -0,0 +1,7 @@ +export function safeRedirectPath(path: string | undefined) { + if (!path) return "/"; + + if (!path.startsWith("/")) return `/${path}`; + + return path; +}