mirror of
https://github.com/fosrl/pangolin.git
synced 2026-09-22 05:49:05 +02:00
Only accept http(s) targets for the resource auth redirect
The resource auth page copies the redirect query parameter into redirectUrl when its host matches the resource host (src/app/auth/resource/[resourceGuid]/page.tsx:121-150). URL parses a host out of every scheme that uses "//", so a target such as javascript://resource-host/... passes that comparison. The value is handed to ResourceAuthPortal as the redirect prop and assigned to window.location.href after a successful login (src/components/ResourceAuthPortal.tsx:213,247,281). Parse the target once and require http: or https: before the host comparisons. The three branches that assigned the same value are folded into one condition; the accepted set of http(s) targets is unchanged.
This commit is contained in:
@@ -122,11 +122,20 @@ export default async function ResourceAuthPage(props: {
|
||||
|
||||
if (searchParams.redirect) {
|
||||
try {
|
||||
const redirectTarget = new URL(searchParams.redirect);
|
||||
const serverResourceHost = new URL(authInfo.url).host;
|
||||
const redirectHost = new URL(searchParams.redirect).host;
|
||||
const redirectPort = new URL(searchParams.redirect).port;
|
||||
const redirectHost = redirectTarget.host;
|
||||
const redirectPort = redirectTarget.port;
|
||||
const serverResourceHostWithPort = `${serverResourceHost}:${redirectPort}`;
|
||||
|
||||
// URL parses a host out of any scheme that uses "//", so a target
|
||||
// like javascript://resource-host/... matches the comparisons
|
||||
// below. The target is later assigned to window.location, so only
|
||||
// http(s) is accepted here.
|
||||
const isHttpTarget =
|
||||
redirectTarget.protocol === "http:" ||
|
||||
redirectTarget.protocol === "https:";
|
||||
|
||||
const wildcardMatchesRedirect = (
|
||||
wildcardDomain: string,
|
||||
host: string
|
||||
@@ -136,14 +145,16 @@ export default async function ResourceAuthPage(props: {
|
||||
return host.endsWith(suffix) && host.length > suffix.length;
|
||||
};
|
||||
|
||||
if (serverResourceHost === redirectHost) {
|
||||
redirectUrl = searchParams.redirect;
|
||||
} else if (serverResourceHostWithPort === redirectHost) {
|
||||
redirectUrl = searchParams.redirect;
|
||||
} else if (
|
||||
authInfo.wildcard &&
|
||||
authInfo.fullDomain &&
|
||||
wildcardMatchesRedirect(authInfo.fullDomain, redirectHost)
|
||||
if (
|
||||
isHttpTarget &&
|
||||
(serverResourceHost === redirectHost ||
|
||||
serverResourceHostWithPort === redirectHost ||
|
||||
(authInfo.wildcard &&
|
||||
authInfo.fullDomain &&
|
||||
wildcardMatchesRedirect(
|
||||
authInfo.fullDomain,
|
||||
redirectHost
|
||||
)))
|
||||
) {
|
||||
redirectUrl = searchParams.redirect;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user