Skip to content

Commit 14afbd3

Browse files
RonenMarsclaude
andcommitted
feat: add OAuth redirect URL validation for security
- Add validateOAuthRedirectURL utility function with domain allowlist - Enforce HTTPS requirement for all OAuth redirect URLs - Validate OAuth provider domains against security allowlist - Integrate URL validation into login component OAuth flow - Add comprehensive logging for security validation events Security improvements: - Prevent open redirect vulnerabilities - Restrict OAuth flows to trusted provider domains - Add runtime validation with detailed error logging 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e4572a2 commit 14afbd3

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

src/components/pages/login.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useSearchParams } from "react-router-dom";
77
import { isDevelopment } from "@constants/global.constants";
88
import { LoggerService } from "@services";
99
import { LoginPageProps } from "@src/interfaces/components";
10+
import { validateOAuthRedirectURL } from "@utilities/validateUrl.utils";
1011

1112
import { AHref, IconSvg, Loader } from "@components/atoms";
1213
import { OAuthProviderButton } from "@components/molecules";
@@ -75,8 +76,15 @@ const Login = ({ handleSuccess, isLoggingIn }: LoginPageProps) => {
7576
LoggerService.debug("auth.oauth.login", `OAuth start successful, redirecting to: ${resp?.data?.url}`);
7677
}
7778

78-
// TODO: Add URL validation before redirect
79-
window.location.href = resp?.data?.url;
79+
// Validate OAuth redirect URL for security
80+
const redirectUrl = resp?.data?.url;
81+
if (!redirectUrl || !validateOAuthRedirectURL(redirectUrl)) {
82+
LoggerService.error("auth.oauth.login", `Invalid OAuth redirect URL received: ${redirectUrl}`, true);
83+
// TODO: Show user-friendly error notification
84+
return;
85+
}
86+
87+
window.location.href = redirectUrl;
8088
} catch (error) {
8189
LoggerService.error("auth.oauth.login", `Error initiating OAuth: ${error}`, true);
8290
// TODO: Show user-friendly error notification

src/utilities/validateUrl.utils.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,41 @@ export const compareUrlParams = (oldUrl: string, newUrl: string): boolean => {
3636
return oldUrl !== newUrl;
3737
}
3838
};
39+
40+
// Allowed OAuth provider domains for security
41+
const allowedOAuthDomains = [
42+
"github.com",
43+
"api.github.com",
44+
"accounts.google.com",
45+
"login.microsoftonline.com",
46+
"oauth.descope.com",
47+
"api.descope.com",
48+
] as const;
49+
50+
export const validateOAuthRedirectURL = (url: string): boolean => {
51+
try {
52+
// First check if it's a valid URL
53+
const parsedUrl = new URL(url);
54+
55+
// Must be HTTPS for security
56+
if (parsedUrl.protocol !== "https:") {
57+
LoggerService.warn("auth.oauth.validation", `OAuth redirect URL must use HTTPS: ${url}`);
58+
return false;
59+
}
60+
61+
// Check if the domain is in our allowlist
62+
const isAllowedDomain = allowedOAuthDomains.some(
63+
(domain) => parsedUrl.hostname === domain || parsedUrl.hostname.endsWith(`.${domain}`)
64+
);
65+
66+
if (!isAllowedDomain) {
67+
LoggerService.warn("auth.oauth.validation", `OAuth redirect URL domain not allowed: ${parsedUrl.hostname}`);
68+
return false;
69+
}
70+
71+
return true;
72+
} catch (error) {
73+
LoggerService.error("auth.oauth.validation", `Invalid OAuth redirect URL: ${url}, Error: ${error}`);
74+
return false;
75+
}
76+
};

0 commit comments

Comments
 (0)