From aacbbc1785379c8b4e8b8d29ff3c622791d3bfa7 Mon Sep 17 00:00:00 2001 From: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Date: Fri, 20 Jun 2025 20:17:56 +0530 Subject: [PATCH] fix: Rate limit /router endpoint (#21940) * fix: add rate limiting for /router/embed * Abstract out hashing code --------- Co-authored-by: Hariom --- packages/lib/server/getRoutedUrl.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/lib/server/getRoutedUrl.ts b/packages/lib/server/getRoutedUrl.ts index 23e68a9509..ff03920863 100644 --- a/packages/lib/server/getRoutedUrl.ts +++ b/packages/lib/server/getRoutedUrl.ts @@ -1,4 +1,5 @@ // !IMPORTANT! changes to this file requires publishing new version of platform libraries in order for the changes to be applied to APIV2 +import { createHash } from "crypto"; import type { GetServerSidePropsContext } from "next"; import { stringify } from "querystring"; import { v4 as uuidv4 } from "uuid"; @@ -16,6 +17,7 @@ import { getUrlSearchParamsToForward } from "@calcom/app-store/routing-forms/pag import type { FormResponse } from "@calcom/app-store/routing-forms/types/types"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; import { isAuthorizedToViewFormOnOrgDomain } from "@calcom/features/routing-forms/lib/isAuthorizedToViewForm"; +import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import logger from "@calcom/lib/logger"; import { withReporting } from "@calcom/lib/sentryWrapper"; import { RoutingFormRepository } from "@calcom/lib/server/repository/routingForm"; @@ -30,6 +32,18 @@ const querySchema = z }) .catchall(z.string().or(z.array(z.string()))); +const getDeterministicHashForResponse = (fieldsResponses: Record) => { + const sortedFields = Object.keys(fieldsResponses) + .sort() + .reduce((obj: Record, key) => { + obj[key] = fieldsResponses[key]; + return obj; + }, {}); + const paramsString = JSON.stringify(sortedFields); + const hash = createHash("sha256").update(paramsString).digest("hex"); + return hash; +}; + function hasEmbedPath(pathWithQuery: string) { const onlyPath = pathWithQuery.split("?")[0]; return onlyPath.endsWith("/embed") || onlyPath.endsWith("/embed/"); @@ -57,6 +71,13 @@ const _getRoutedUrl = async (context: Pick