Skip to content

Commit db8ca6c

Browse files
krancourrpelczar
andauthored
Merge commit from fork
* fix(ui): Open Redirect through redirectTo parameter Signed-off-by: Rafal Pelczar <rafal@akuity.io> * fix oidc login redirection Signed-off-by: Rafal Pelczar <rafal@akuity.io> --------- Signed-off-by: Rafal Pelczar <rafal@akuity.io> Co-authored-by: Rafal Pelczar <rafal@akuity.io>
1 parent 9264c73 commit db8ca6c

4 files changed

Lines changed: 18 additions & 5 deletions

File tree

ui/src/config/auth.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,13 @@ export const authTokenKey = 'auth_token';
22
export const refreshTokenKey = 'refresh_token';
33

44
export const redirectToQueryParam = 'redirectTo';
5+
6+
// Validate that a redirect path is a safe, same-origin relative path.
7+
export const isSafeRedirectPath = (path: string | null): path is string => {
8+
if (!path || !path.startsWith('/')) return false;
9+
try {
10+
return new URL(path, window.location.origin).origin === window.location.origin;
11+
} catch {
12+
return false;
13+
}
14+
};

ui/src/features/auth/oidc-login.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import React from 'react';
1717
import { useLocation } from 'react-router-dom';
1818

19+
import { isSafeRedirectPath } from '@ui/config/auth';
1920
import { OIDCConfig } from '@ui/gen/api/service/v1alpha1/service_pb';
2021

2122
import { useAuthContext } from './context/use-auth-context';
@@ -151,7 +152,7 @@ export const OIDCLogin = ({ oidcConfig }: Props) => {
151152
if (platformRedirect) {
152153
const redirectTo = new URLSearchParams(platformRedirect).get('redirectTo');
153154

154-
if (redirectTo) {
155+
if (isSafeRedirectPath(redirectTo)) {
155156
window.location.replace(window.location.origin + redirectTo);
156157
}
157158
}

ui/src/features/auth/token-renew.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import React from 'react';
1212
import { useNavigate, useSearchParams } from 'react-router-dom';
1313

14-
import { redirectToQueryParam, refreshTokenKey } from '@ui/config/auth';
14+
import { isSafeRedirectPath, redirectToQueryParam, refreshTokenKey } from '@ui/config/auth';
1515
import { paths } from '@ui/config/paths';
1616
import { getPublicConfig } from '@ui/gen/api/service/v1alpha1/service-KargoService_connectquery';
1717

@@ -72,6 +72,7 @@ export const TokenRenew = () => {
7272

7373
(async () => {
7474
const redirectQuery = searchParams.get(redirectToQueryParam);
75+
const safeRedirectQuery = isSafeRedirectPath(redirectQuery) ? redirectQuery : null;
7576
try {
7677
const response = await refreshTokenGrantRequest(as, client, oidcClientAuth, refreshToken, {
7778
[allowInsecureRequests]: shouldAllowHttpRequest(),
@@ -93,7 +94,7 @@ export const TokenRenew = () => {
9394
}
9495

9596
onLogin(result.id_token, result.refresh_token);
96-
navigate(redirectQuery || paths.home);
97+
navigate(safeRedirectQuery || paths.home);
9798
} catch (err) {
9899
logout();
99100
navigate(

ui/src/pages/login/login.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useQuery } from '@connectrpc/connect-query';
22
import { Divider, Typography } from 'antd';
33
import { Navigate, generatePath, useSearchParams } from 'react-router-dom';
44

5-
import { redirectToQueryParam } from '@ui/config/auth';
5+
import { isSafeRedirectPath, redirectToQueryParam } from '@ui/config/auth';
66
import { paths } from '@ui/config/paths';
77
import { AdminLogin } from '@ui/features/auth/admin-login';
88
import { useAuthContext } from '@ui/features/auth/context/use-auth-context';
@@ -18,13 +18,14 @@ export const Login = () => {
1818
const [params] = useSearchParams();
1919
const { isLoggedIn } = useAuthContext();
2020
const redirectTo = params.get(redirectToQueryParam);
21+
const safeRedirectTo = isSafeRedirectPath(redirectTo) ? redirectTo : null;
2122

2223
if (data?.skipAuth) {
2324
return <Navigate to={paths.home} replace />;
2425
}
2526

2627
if (isLoggedIn) {
27-
return <Navigate to={redirectTo ? generatePath(redirectTo) : paths.home} replace />;
28+
return <Navigate to={safeRedirectTo ? generatePath(safeRedirectTo) : paths.home} replace />;
2829
}
2930

3031
return (

0 commit comments

Comments
 (0)