Make sure that absolute URL is of WEBAPP only (#2624)

pull/2674/head
Hariom Balhara 2022-04-27 19:58:36 +05:30 committed by Omar López
parent 59c0784cd6
commit a224a46654
6 changed files with 29 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import { useRouter } from "next/router";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { Alert } from "@calcom/ui/Alert";
import Button from "@calcom/ui/Button";
import { EmailField, Form, PasswordField } from "@calcom/ui/form/fields";
@ -61,12 +62,15 @@ export default function Login({
let callbackUrl = typeof router.query?.callbackUrl === "string" ? router.query.callbackUrl : "";
// If not absolute URL, make it absolute
if (/"\//.test(callbackUrl)) callbackUrl = callbackUrl.substring(1);
// If not absolute URL, make it absolute
if (!/^https?:\/\//.test(callbackUrl)) {
callbackUrl = `${WEBAPP_URL}/${callbackUrl}`;
}
callbackUrl = getSafeRedirectUrl(callbackUrl);
const LoginFooter = (
<span>
{t("dont_have_an_account")}{" "}

View File

@ -2,6 +2,7 @@ import { google } from "googleapis";
import type { NextApiRequest, NextApiResponse } from "next";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import prisma from "@calcom/prisma";
import { decodeOAuthState } from "../../_utils/decodeOAuthState";
@ -10,7 +11,6 @@ const credentials = process.env.GOOGLE_API_CREDENTIALS;
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { code } = req.query;
if (code && typeof code !== "string") {
res.status(400).json({ message: "`code` must be a string" });
return;
@ -19,7 +19,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
res.status(400).json({ message: "There are no Google Credentials installed." });
return;
}
const { client_secret, client_id } = JSON.parse(credentials).web;
const redirect_uri = WEBAPP_URL + "/api/integrations/googlecalendar/callback";
@ -41,5 +40,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
},
});
const state = decodeOAuthState(req);
res.redirect(state?.returnTo ?? "/apps/installed");
res.redirect(getSafeRedirectUrl(state?.returnTo) ?? "/apps/installed");
}

View File

@ -3,6 +3,7 @@ import { TokenResponseIF } from "@hubspot/api-client/lib/codegen/oauth/models/To
import type { NextApiRequest, NextApiResponse } from "next";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import prisma from "@calcom/prisma";
import { decodeOAuthState } from "../../_utils/decodeOAuthState";
@ -52,5 +53,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
const state = decodeOAuthState(req);
res.redirect(state?.returnTo ?? "/apps/installed");
res.redirect(getSafeRedirectUrl(state?.returnTo) ?? "/apps/installed");
}

View File

@ -1,6 +1,7 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { BASE_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import prisma from "@calcom/prisma";
import { decodeOAuthState } from "../../_utils/decodeOAuthState";
@ -62,5 +63,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
const state = decodeOAuthState(req);
return res.redirect(state?.returnTo ?? "/apps/installed");
return res.redirect(getSafeRedirectUrl(state?.returnTo) ?? "/apps/installed");
}

View File

@ -1,6 +1,7 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { BASE_URL } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import prisma from "@calcom/prisma";
import { decodeOAuthState } from "../../_utils/decodeOAuthState";
@ -63,5 +64,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
const state = decodeOAuthState(req);
return res.redirect(state?.returnTo ?? "/apps/installed");
return res.redirect(getSafeRedirectUrl(state?.returnTo) ?? "/apps/installed");
}

View File

@ -0,0 +1,16 @@
import { WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
// It ensures that redirection URL safe where it is accepted through a query params or other means where user can change it.
export const getSafeRedirectUrl = (url: string | undefined) => {
url = url || "";
if (url.search(/^https?:\/\//) === -1) {
throw new Error("Pass an absolute URL");
}
// Avoid open redirection security vulnerability
if (!url.startsWith(WEBAPP_URL) && !url.startsWith(WEBSITE_URL)) {
url = `${WEBAPP_URL}/`;
}
return url;
};