diff --git a/.changeset/breezy-horses-marry.md b/.changeset/breezy-horses-marry.md
new file mode 100644
index 0000000000000..eacb88108a0f7
--- /dev/null
+++ b/.changeset/breezy-horses-marry.md
@@ -0,0 +1,5 @@
+---
+'@rocket.chat/meteor': patch
+---
+
+Security Hotfix (https://docs.rocket.chat/docs/security-fixes-and-updates)
diff --git a/apps/meteor/app/cors/server/cors.ts b/apps/meteor/app/cors/server/cors.ts
index 3090530140168..effbb712681b1 100644
--- a/apps/meteor/app/cors/server/cors.ts
+++ b/apps/meteor/app/cors/server/cors.ts
@@ -4,6 +4,7 @@ import type { UrlWithParsedQuery } from 'url';
 import url from 'url';
 
 import { Logger } from '@rocket.chat/logger';
+import { OAuthApps } from '@rocket.chat/models';
 import { Meteor } from 'meteor/meteor';
 import type { StaticFiles } from 'meteor/webapp';
 import { WebApp, WebAppInternals } from 'meteor/webapp';
@@ -48,10 +49,13 @@ WebApp.rawConnectHandlers.use(async (_req: http.IncomingMessage, res: http.Serve
 	}
 
 	if (settings.get<boolean>('Enable_CSP')) {
+		const legacyZapierAvailable = Boolean(await OAuthApps.findOneById('zapier'));
+
 		// eslint-disable-next-line @typescript-eslint/naming-convention
 		const cdn_prefixes = [
 			settings.get<string>('CDN_PREFIX'),
 			settings.get<string>('CDN_PREFIX_ALL') ? null : settings.get<string>('CDN_JSCSS_PREFIX'),
+			legacyZapierAvailable && 'https://cdn.zapier.com',
 		]
 			.filter(Boolean)
 			.join(' ');
@@ -68,6 +72,7 @@ WebApp.rawConnectHandlers.use(async (_req: http.IncomingMessage, res: http.Serve
 			settings.get<boolean>('Accounts_OAuth_Apple') && 'https://appleid.cdn-apple.com',
 			settings.get<boolean>('PiwikAnalytics_enabled') && settings.get('PiwikAnalytics_url'),
 			settings.get<boolean>('GoogleAnalytics_enabled') && 'https://www.google-analytics.com',
+			legacyZapierAvailable && 'https://zapier.com',
 			...settings
 				.get<string>('Extra_CSP_Domains')
 				.split(/[ \n\,]/gim)
diff --git a/apps/meteor/app/oauth2-server-config/server/index.ts b/apps/meteor/app/oauth2-server-config/server/index.ts
index be26bdb2facb1..3914cac5eaadc 100644
--- a/apps/meteor/app/oauth2-server-config/server/index.ts
+++ b/apps/meteor/app/oauth2-server-config/server/index.ts
@@ -1,5 +1,4 @@
 import './oauth/oauth2-server';
-import './oauth/default-services';
 import './admin/functions/addOAuthApp';
 import './admin/methods/updateOAuthApp';
 import './admin/methods/deleteOAuthApp';
diff --git a/apps/meteor/app/oauth2-server-config/server/oauth/default-services.ts b/apps/meteor/app/oauth2-server-config/server/oauth/default-services.ts
deleted file mode 100644
index cd2d4e6c862d0..0000000000000
--- a/apps/meteor/app/oauth2-server-config/server/oauth/default-services.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { OAuthApps } from '@rocket.chat/models';
-
-async function run(): Promise<void> {
-	if (!(await OAuthApps.findOneById('zapier'))) {
-		await OAuthApps.insertOne({
-			_id: 'zapier',
-			name: 'Zapier',
-			active: true,
-			clientId: 'zapier',
-			clientSecret: 'RTK6TlndaCIolhQhZ7_KHIGOKj41RnlaOq_o-7JKwLr',
-			redirectUri: 'https://zapier.com/dashboard/auth/oauth/return/RocketChatDevAPI/',
-			_createdAt: new Date(),
-			_createdBy: {
-				_id: 'system',
-				username: 'system',
-			},
-		});
-	}
-}
-
-void run();
diff --git a/apps/meteor/client/components/FingerprintChangeModal.tsx b/apps/meteor/client/components/FingerprintChangeModal.tsx
index 834f130bb9f1a..354d13df06c24 100644
--- a/apps/meteor/client/components/FingerprintChangeModal.tsx
+++ b/apps/meteor/client/components/FingerprintChangeModal.tsx
@@ -1,4 +1,5 @@
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { useTranslation } from 'react-i18next';
 
@@ -26,14 +27,17 @@ const FingerprintChangeModal = ({ onConfirm, onCancel, onClose }: FingerprintCha
 				is='p'
 				mbe={16}
 				dangerouslySetInnerHTML={{
-					__html: t('Unique_ID_change_detected_description'),
+					__html: DOMPurify.sanitize(t('Unique_ID_change_detected_description')),
 				}}
 			/>
 			<Box
 				is='p'
 				mbe={16}
 				dangerouslySetInnerHTML={{
-					__html: t('Unique_ID_change_detected_learn_more_link'),
+					__html: DOMPurify.sanitize(t('Unique_ID_change_detected_learn_more_link'), {
+						ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
+						ALLOWED_ATTR: ['href', 'title'],
+					}),
 				}}
 			/>
 		</GenericModal>
diff --git a/apps/meteor/client/components/FingerprintChangeModalConfirmation.tsx b/apps/meteor/client/components/FingerprintChangeModalConfirmation.tsx
index 7b0d93146a599..7d262d7929355 100644
--- a/apps/meteor/client/components/FingerprintChangeModalConfirmation.tsx
+++ b/apps/meteor/client/components/FingerprintChangeModalConfirmation.tsx
@@ -1,4 +1,5 @@
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { useTranslation } from 'react-i18next';
 
@@ -29,14 +30,19 @@ const FingerprintChangeModalConfirmation = ({
 				is='p'
 				mbe={16}
 				dangerouslySetInnerHTML={{
-					__html: newWorkspace ? t('Confirm_new_workspace_description') : t('Confirm_configuration_update_description'),
+					__html: newWorkspace
+						? DOMPurify.sanitize(t('Confirm_new_workspace_description'))
+						: DOMPurify.sanitize(t('Confirm_configuration_update_description')),
 				}}
 			/>
 			<Box
 				is='p'
 				mbe={16}
 				dangerouslySetInnerHTML={{
-					__html: t('Unique_ID_change_detected_learn_more_link'),
+					__html: DOMPurify.sanitize(t('Unique_ID_change_detected_learn_more_link'), {
+						ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
+						ALLOWED_ATTR: ['href', 'title'],
+					}),
 				}}
 			/>
 		</GenericModal>
diff --git a/apps/meteor/client/components/RawText.tsx b/apps/meteor/client/components/RawText.tsx
index a4220371666f4..58ae89e4d041c 100644
--- a/apps/meteor/client/components/RawText.tsx
+++ b/apps/meteor/client/components/RawText.tsx
@@ -1,6 +1,9 @@
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 
 /** @deprecated */
-const RawText = ({ children }: { children: string }): ReactElement => <span dangerouslySetInnerHTML={{ __html: children }} />;
+const RawText = ({ children }: { children: string }): ReactElement => (
+	<span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(children) }} />
+);
 
 export default RawText;
diff --git a/apps/meteor/client/components/RoomIcon/OmnichannelRoomIcon/provider/OmnichannelRoomIconProvider.tsx b/apps/meteor/client/components/RoomIcon/OmnichannelRoomIcon/provider/OmnichannelRoomIconProvider.tsx
index 57febd38b9e36..305359f1be9be 100644
--- a/apps/meteor/client/components/RoomIcon/OmnichannelRoomIcon/provider/OmnichannelRoomIconProvider.tsx
+++ b/apps/meteor/client/components/RoomIcon/OmnichannelRoomIcon/provider/OmnichannelRoomIconProvider.tsx
@@ -1,3 +1,4 @@
+import DOMPurify from 'dompurify';
 import type { ReactNode } from 'react';
 import { useCallback, useMemo } from 'react';
 import { createPortal } from 'react-dom';
@@ -84,7 +85,11 @@ export const OmnichannelRoomIconProvider = ({ children }: OmnichannelRoomIconPro
 					xmlns='http://www.w3.org/2000/svg'
 					xmlnsXlink='http://www.w3.org/1999/xlink'
 					style={{ display: 'none' }}
-					dangerouslySetInnerHTML={{ __html: svgIcons.join('') }}
+					dangerouslySetInnerHTML={{
+						__html: DOMPurify.sanitize(svgIcons.join(''), {
+							USE_PROFILES: { svg: true, svgFilters: true },
+						}),
+					}}
 				/>,
 				document.body,
 				'custom-icons',
diff --git a/apps/meteor/client/components/UrlChangeModal.tsx b/apps/meteor/client/components/UrlChangeModal.tsx
index cf1df67adf00d..75a5310861c8e 100644
--- a/apps/meteor/client/components/UrlChangeModal.tsx
+++ b/apps/meteor/client/components/UrlChangeModal.tsx
@@ -1,4 +1,5 @@
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { useTranslation } from 'react-i18next';
 
@@ -19,18 +20,22 @@ const UrlChangeModal = ({ onConfirm, siteUrl, currentUrl, onClose }: UrlChangeMo
 				is='p'
 				mbe={16}
 				dangerouslySetInnerHTML={{
-					__html: t('The_setting_s_is_configured_to_s_and_you_are_accessing_from_s', {
-						postProcess: 'sprintf',
-						sprintf: [t('Site_Url'), siteUrl, currentUrl],
-					}),
+					__html: DOMPurify.sanitize(
+						t('The_setting_s_is_configured_to_s_and_you_are_accessing_from_s', {
+							postProcess: 'sprintf',
+							sprintf: [t('Site_Url'), siteUrl, currentUrl],
+						}),
+					),
 				}}
 			/>
 			<p
 				dangerouslySetInnerHTML={{
-					__html: t('Do_you_want_to_change_to_s_question', {
-						postProcess: 'sprintf',
-						sprintf: [currentUrl],
-					}),
+					__html: DOMPurify.sanitize(
+						t('Do_you_want_to_change_to_s_question', {
+							postProcess: 'sprintf',
+							sprintf: [currentUrl],
+						}),
+					),
 				}}
 			/>
 		</GenericModal>
diff --git a/apps/meteor/client/lib/utils/createToken.ts b/apps/meteor/client/lib/utils/createToken.ts
index 0795f8103fd18..25360b773ba9c 100644
--- a/apps/meteor/client/lib/utils/createToken.ts
+++ b/apps/meteor/client/lib/utils/createToken.ts
@@ -1 +1,14 @@
-export const createToken = (): string => Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
+export const createToken = (): string => {
+	const array = new Uint8Array(16);
+	if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {
+		window.crypto.getRandomValues(array);
+	} else {
+		// Use Node.js crypto
+		const { randomBytes } = require('crypto'); // eslint-disable-line @typescript-eslint/no-var-requires
+		const buffer = randomBytes(16);
+		array.set(buffer);
+	}
+	return Array.from(array)
+		.map((byte) => byte.toString(16).padStart(2, '0'))
+		.join('');
+};
diff --git a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx
index 4add7090a6db9..9e22fe1ea318d 100644
--- a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx
+++ b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx
@@ -2,6 +2,7 @@ import type { IMessage, IRoom, ISubscription } from '@rocket.chat/core-typings';
 import { isDirectMessageRoom, isMultipleDirectMessageRoom, isOmnichannelRoom, isVideoConfMessage } from '@rocket.chat/core-typings';
 import { Badge, Sidebar, SidebarItemAction, SidebarItemActions, Margins } from '@rocket.chat/fuselage';
 import { useLayout } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import type { TFunction } from 'i18next';
 import type { AllHTMLAttributes, ComponentType, ReactElement, ReactNode } from 'react';
 import { memo, useMemo } from 'react';
@@ -147,7 +148,9 @@ function SideBarItemTemplateWithData({
 	const { enabled: isPriorityEnabled } = useOmnichannelPriorities();
 
 	const message = extended && getMessage(room, lastMessage, t);
-	const subtitle = message ? <span className='message-body--unstyled' dangerouslySetInnerHTML={{ __html: message }} /> : null;
+	const subtitle = message ? (
+		<span className='message-body--unstyled' dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(message) }} />
+	) : null;
 
 	const threadUnread = tunread.length > 0;
 	const variant =
diff --git a/apps/meteor/client/sidebar/footer/SidebarFooterDefault.tsx b/apps/meteor/client/sidebar/footer/SidebarFooterDefault.tsx
index 66e5150ab2e14..291799c361d36 100644
--- a/apps/meteor/client/sidebar/footer/SidebarFooterDefault.tsx
+++ b/apps/meteor/client/sidebar/footer/SidebarFooterDefault.tsx
@@ -2,6 +2,7 @@ import { css } from '@rocket.chat/css-in-js';
 import { Box, SidebarDivider, Palette, SidebarFooter as Footer } from '@rocket.chat/fuselage';
 import { useSetting } from '@rocket.chat/ui-contexts';
 import { useThemeMode } from '@rocket.chat/ui-theming';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 
 import { SidebarFooterWatermark } from './SidebarFooterWatermark';
@@ -32,7 +33,7 @@ const SidebarFooterDefault = (): ReactElement => {
 				width='auto'
 				className={sidebarFooterStyle}
 				dangerouslySetInnerHTML={{
-					__html: logo,
+					__html: DOMPurify.sanitize(logo),
 				}}
 			/>
 			<SidebarFooterWatermark />
diff --git a/apps/meteor/client/sidebarv2/footer/SidebarFooterDefault.tsx b/apps/meteor/client/sidebarv2/footer/SidebarFooterDefault.tsx
index 66e5150ab2e14..291799c361d36 100644
--- a/apps/meteor/client/sidebarv2/footer/SidebarFooterDefault.tsx
+++ b/apps/meteor/client/sidebarv2/footer/SidebarFooterDefault.tsx
@@ -2,6 +2,7 @@ import { css } from '@rocket.chat/css-in-js';
 import { Box, SidebarDivider, Palette, SidebarFooter as Footer } from '@rocket.chat/fuselage';
 import { useSetting } from '@rocket.chat/ui-contexts';
 import { useThemeMode } from '@rocket.chat/ui-theming';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 
 import { SidebarFooterWatermark } from './SidebarFooterWatermark';
@@ -32,7 +33,7 @@ const SidebarFooterDefault = (): ReactElement => {
 				width='auto'
 				className={sidebarFooterStyle}
 				dangerouslySetInnerHTML={{
-					__html: logo,
+					__html: DOMPurify.sanitize(logo),
 				}}
 			/>
 			<SidebarFooterWatermark />
diff --git a/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.tsx b/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.tsx
index 53e91211a49d0..bffd31cda9042 100644
--- a/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.tsx
+++ b/apps/meteor/client/views/account/preferences/PreferencesMyDataSection.tsx
@@ -1,5 +1,6 @@
 import { AccordionItem, ButtonGroup, Button, Box } from '@rocket.chat/fuselage';
 import { useSetModal, useToastMessageDispatch, useMethod } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { useCallback } from 'react';
 import { useTranslation } from 'react-i18next';
 
@@ -23,7 +24,7 @@ const PreferencesMyDataSection = () => {
 					setModal(
 						<MyDataModal
 							title={t('UserDataDownload_Requested')}
-							text={<Box dangerouslySetInnerHTML={{ __html: text }} />}
+							text={<Box dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(text) }} />}
 							onCancel={() => setModal(null)}
 						/>,
 					);
@@ -41,7 +42,7 @@ const PreferencesMyDataSection = () => {
 						setModal(
 							<MyDataModal
 								title={t('UserDataDownload_Requested')}
-								text={<Box dangerouslySetInnerHTML={{ __html: text }} />}
+								text={<Box dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(text) }} />}
 								onCancel={() => setModal(null)}
 							/>,
 						);
@@ -55,7 +56,7 @@ const PreferencesMyDataSection = () => {
 					setModal(
 						<MyDataModal
 							title={t('UserDataDownload_Requested')}
-							text={<Box dangerouslySetInnerHTML={{ __html: text }} />}
+							text={<Box dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(text) }} />}
 							onCancel={() => setModal(null)}
 						/>,
 					);
diff --git a/apps/meteor/client/views/account/security/EndToEnd.tsx b/apps/meteor/client/views/account/security/EndToEnd.tsx
index 6eb16d62aea92..c892f4e93cb0a 100644
--- a/apps/meteor/client/views/account/security/EndToEnd.tsx
+++ b/apps/meteor/client/views/account/security/EndToEnd.tsx
@@ -1,6 +1,7 @@
 import { Box, PasswordInput, Field, FieldGroup, FieldLabel, FieldRow, FieldError, FieldHint, Button, Divider } from '@rocket.chat/fuselage';
 import { useUniqueId } from '@rocket.chat/fuselage-hooks';
 import { useToastMessageDispatch, useMethod, useTranslation, useLogout } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { Accounts } from 'meteor/accounts-base';
 import type { ComponentProps, ReactElement } from 'react';
 import { useCallback, useEffect } from 'react';
@@ -76,7 +77,7 @@ const EndToEnd = (props: ComponentProps<typeof Box>): ReactElement => {
 				is='p'
 				fontScale='p1'
 				id={e2ePasswordExplanationId}
-				dangerouslySetInnerHTML={{ __html: t('E2E_Encryption_Password_Explanation') }}
+				dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('E2E_Encryption_Password_Explanation')) }}
 			/>
 
 			<Box mbs={36} w='full'>
@@ -160,7 +161,7 @@ const EndToEnd = (props: ComponentProps<typeof Box>): ReactElement => {
 				<Box is='h4' fontScale='h4' mbe={12}>
 					{t('Reset_E2E_Key')}
 				</Box>
-				<Box is='p' fontScale='p1' mbe={12} dangerouslySetInnerHTML={{ __html: t('E2E_Reset_Key_Explanation') }} />
+				<Box is='p' fontScale='p1' mbe={12} dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('E2E_Reset_Key_Explanation')) }} />
 				<Button onClick={handleResetE2eKey} data-qa-type='e2e-encryption-reset-key-button'>
 					{t('Reset_E2E_Key')}
 				</Button>
diff --git a/apps/meteor/client/views/account/tokens/AccountTokensTable/AccountTokensTable.tsx b/apps/meteor/client/views/account/tokens/AccountTokensTable/AccountTokensTable.tsx
index 833b133f0c087..d1c3365b9df18 100644
--- a/apps/meteor/client/views/account/tokens/AccountTokensTable/AccountTokensTable.tsx
+++ b/apps/meteor/client/views/account/tokens/AccountTokensTable/AccountTokensTable.tsx
@@ -1,5 +1,6 @@
 import { Box, Pagination, States, StatesAction, StatesActions, StatesIcon, StatesSubtitle, StatesTitle } from '@rocket.chat/fuselage';
 import { useSetModal, useToastMessageDispatch, useUserId, useMethod } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import type { ReactElement, RefObject } from 'react';
 import { useMemo, useCallback } from 'react';
 import { useTranslation } from 'react-i18next';
@@ -68,10 +69,12 @@ const AccountTokensTable = (): ReactElement => {
 						<GenericModal title={t('API_Personal_Access_Token_Generated')} onConfirm={closeModal}>
 							<Box
 								dangerouslySetInnerHTML={{
-									__html: t('API_Personal_Access_Token_Generated_Text_Token_s_UserId_s', {
-										token,
-										userId,
-									}),
+									__html: DOMPurify.sanitize(
+										t('API_Personal_Access_Token_Generated_Text_Token_s_UserId_s', {
+											token,
+											userId,
+										}),
+									),
 								}}
 							/>
 						</GenericModal>,
diff --git a/apps/meteor/client/views/account/tokens/AccountTokensTable/AddToken.tsx b/apps/meteor/client/views/account/tokens/AccountTokensTable/AddToken.tsx
index a4d6ef483ca54..fc1d715b5249e 100644
--- a/apps/meteor/client/views/account/tokens/AccountTokensTable/AddToken.tsx
+++ b/apps/meteor/client/views/account/tokens/AccountTokensTable/AddToken.tsx
@@ -1,6 +1,7 @@
 import type { SelectOption } from '@rocket.chat/fuselage';
 import { Box, TextInput, Button, Margins, Select } from '@rocket.chat/fuselage';
 import { useSetModal, useToastMessageDispatch, useUserId, useMethod } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { useCallback, useMemo, useEffect } from 'react';
 import { Controller, useForm } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
@@ -50,10 +51,12 @@ const AddToken = ({ reload }: AddTokenProps) => {
 					<GenericModal title={t('API_Personal_Access_Token_Generated')} onConfirm={() => setModal(null)} onClose={() => setModal(null)}>
 						<Box
 							dangerouslySetInnerHTML={{
-								__html: t('API_Personal_Access_Token_Generated_Text_Token_s_UserId_s', {
-									token,
-									userId,
-								}),
+								__html: DOMPurify.sanitize(
+									t('API_Personal_Access_Token_Generated_Text_Token_s_UserId_s', {
+										token,
+										userId,
+									}),
+								),
 							}}
 						/>
 					</GenericModal>,
diff --git a/apps/meteor/client/views/admin/integrations/NewBot.tsx b/apps/meteor/client/views/admin/integrations/NewBot.tsx
index 2294f9cb91555..efa50938534fb 100644
--- a/apps/meteor/client/views/admin/integrations/NewBot.tsx
+++ b/apps/meteor/client/views/admin/integrations/NewBot.tsx
@@ -1,10 +1,23 @@
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import { useTranslation } from 'react-i18next';
 
 const NewBot = () => {
 	const { t } = useTranslation();
 
-	return <Box pb={20} fontScale='h4' key='bots' dangerouslySetInnerHTML={{ __html: t('additional_integrations_Bots') }} />;
+	return (
+		<Box
+			pb={20}
+			fontScale='h4'
+			key='bots'
+			dangerouslySetInnerHTML={{
+				__html: DOMPurify.sanitize(t('additional_integrations_Bots'), {
+					ALLOWED_TAGS: ['a'],
+					ALLOWED_ATTR: ['href', 'target'],
+				}),
+			}}
+		/>
+	);
 };
 
 export default NewBot;
diff --git a/apps/meteor/client/views/admin/integrations/NewZapier.tsx b/apps/meteor/client/views/admin/integrations/NewZapier.tsx
index 565b371f18f61..1842047aa8c52 100644
--- a/apps/meteor/client/views/admin/integrations/NewZapier.tsx
+++ b/apps/meteor/client/views/admin/integrations/NewZapier.tsx
@@ -2,6 +2,9 @@ import { Box, Skeleton, Margins, Callout } from '@rocket.chat/fuselage';
 import { useEffect, useState } from 'react';
 import { useTranslation } from 'react-i18next';
 
+import { useOAuthAppQuery } from '../../oauth/hooks/useOAuthAppQuery';
+import PageLoading from '../../root/PageLoading';
+
 const blogSpotStyleScriptImport = (src: string) =>
 	new Promise((resolve) => {
 		const script = document.createElement('script');
@@ -17,6 +20,8 @@ const blogSpotStyleScriptImport = (src: string) =>
 
 const NewZapier = ({ ...props }) => {
 	const { t } = useTranslation();
+	const oauthAppQuery = useOAuthAppQuery('zapier');
+	const zapierAvailable = !oauthAppQuery.isLoading && !oauthAppQuery.isError && oauthAppQuery.data;
 	const [script, setScript] = useState<HTMLScriptElement>();
 
 	useEffect(() => {
@@ -28,7 +33,7 @@ const NewZapier = ({ ...props }) => {
 			setScript(scriptEl as HTMLScriptElement);
 		};
 
-		if (!script) {
+		if (!script && zapierAvailable) {
 			importZapier();
 		}
 
@@ -37,25 +42,39 @@ const NewZapier = ({ ...props }) => {
 				script.parentNode?.removeChild(script);
 			}
 		};
-	}, [script]);
+	}, [script, zapierAvailable]);
+
+	if (oauthAppQuery.isLoading) {
+		return <PageLoading />;
+	}
 
 	return (
 		<>
-			<Callout type='warning' icon='warning' title={t('Zapier_integration_has_been_deprecated')} mbs={16} mbe={4}>
-				{t('Install_Zapier_from_marketplace')}
+			<Callout
+				type='warning'
+				icon='warning'
+				title={t(!zapierAvailable ? 'Zapier_integration_is_not_available' : 'Zapier_integration_has_been_deprecated')}
+				mbs={16}
+				mbe={4}
+			>
+				{t(!zapierAvailable ? 'Install_Zapier_from_marketplace_new_workspaces' : 'Install_Zapier_from_marketplace')}
 			</Callout>
-			{!script && (
-				<Box display='flex' flexDirection='column' alignItems='stretch' mbs={10}>
-					<Margins blockEnd={14}>
-						<Skeleton variant='rect' height={71} />
-						<Skeleton variant='rect' height={71} />
-						<Skeleton variant='rect' height={71} />
-						<Skeleton variant='rect' height={71} />
-						<Skeleton variant='rect' height={71} />
-					</Margins>
-				</Box>
+			{zapierAvailable && (
+				<>
+					{!script && (
+						<Box display='flex' flexDirection='column' alignItems='stretch' mbs={10}>
+							<Margins blockEnd={14}>
+								<Skeleton variant='rect' height={71} />
+								<Skeleton variant='rect' height={71} />
+								<Skeleton variant='rect' height={71} />
+								<Skeleton variant='rect' height={71} />
+								<Skeleton variant='rect' height={71} />
+							</Margins>
+						</Box>
+					)}
+					<Box id='zapier-goes-here' {...props} />
+				</>
 			)}
-			<Box id='zapier-goes-here' {...props} />
 		</>
 	);
 };
diff --git a/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx b/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
index 9470ec8ca70c9..2ccd413fb8984 100644
--- a/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
+++ b/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx
@@ -19,6 +19,7 @@ import {
 } from '@rocket.chat/fuselage';
 import { useUniqueId } from '@rocket.chat/fuselage-hooks';
 import { useAbsoluteUrl } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { useMemo } from 'react';
 import { Controller, useFormContext } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
@@ -111,7 +112,7 @@ const IncomingWebhookForm = ({ webhookData }: { webhookData?: Serialized<IIncomi
 							<FieldRow>
 								<Box fontScale='p2' withRichContent flexGrow={1}>
 									<pre>
-										<code dangerouslySetInnerHTML={{ __html: hilightedExampleJson }}></code>
+										<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(hilightedExampleJson) }}></code>
 									</pre>
 								</Box>
 							</FieldRow>
@@ -179,10 +180,12 @@ const IncomingWebhookForm = ({ webhookData }: { webhookData?: Serialized<IIncomi
 							<FieldHint
 								id={`${channelField}-hint-2`}
 								dangerouslySetInnerHTML={{
-									__html: t('Start_with_s_for_user_or_s_for_channel_Eg_s_or_s', {
-										postProcess: 'sprintf',
-										sprintf: ['@', '#', '@john', '#general'],
-									}),
+									__html: DOMPurify.sanitize(
+										t('Start_with_s_for_user_or_s_for_channel_Eg_s_or_s', {
+											postProcess: 'sprintf',
+											sprintf: ['@', '#', '@john', '#general'],
+										}),
+									),
 								}}
 							/>
 							{errors?.channel && (
@@ -271,7 +274,7 @@ const IncomingWebhookForm = ({ webhookData }: { webhookData?: Serialized<IIncomi
 							<FieldHint id={`${emojiField}-hint-1`}>{t('You_can_use_an_emoji_as_avatar')}</FieldHint>
 							<FieldHint
 								id={`${emojiField}-hint-2`}
-								dangerouslySetInnerHTML={{ __html: t('Example_s', { postProcess: 'sprintf', sprintf: [':ghost:'] }) }}
+								dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Example_s', { postProcess: 'sprintf', sprintf: [':ghost:'] })) }}
 							/>
 						</Field>
 						<Field>
diff --git a/apps/meteor/client/views/admin/integrations/outgoing/OutgoingWebhookForm.tsx b/apps/meteor/client/views/admin/integrations/outgoing/OutgoingWebhookForm.tsx
index 3259857f009d9..15db3e86f795f 100644
--- a/apps/meteor/client/views/admin/integrations/outgoing/OutgoingWebhookForm.tsx
+++ b/apps/meteor/client/views/admin/integrations/outgoing/OutgoingWebhookForm.tsx
@@ -18,6 +18,7 @@ import {
 } from '@rocket.chat/fuselage';
 import { useUniqueId } from '@rocket.chat/fuselage-hooks';
 import type { TranslationKey } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { useMemo } from 'react';
 import { useFormContext, Controller } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
@@ -179,13 +180,18 @@ const OutgoingWebhookForm = () => {
 								<FieldHint
 									id={`${channelField}-hint-2`}
 									dangerouslySetInnerHTML={{
-										__html: t('Start_with_s_for_user_or_s_for_channel_Eg_s_or_s', {
-											postProcess: 'sprintf',
-											sprintf: ['@', '#', '@john', '#general'],
-										}),
+										__html: DOMPurify.sanitize(
+											t('Start_with_s_for_user_or_s_for_channel_Eg_s_or_s', {
+												postProcess: 'sprintf',
+												sprintf: ['@', '#', '@john', '#general'],
+											}),
+										),
 									}}
 								/>
-								<FieldHint id={`${channelField}-hint-3`} dangerouslySetInnerHTML={{ __html: t('Integrations_for_all_channels') }} />
+								<FieldHint
+									id={`${channelField}-hint-3`}
+									dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Integrations_for_all_channels')) }}
+								/>
 							</Field>
 						)}
 						{showTriggerWords && (
@@ -226,10 +232,12 @@ const OutgoingWebhookForm = () => {
 								<FieldHint
 									id={`${targetRoomField}-hint-2`}
 									dangerouslySetInnerHTML={{
-										__html: t('Start_with_s_for_user_or_s_for_channel_Eg_s_or_s', {
-											postProcess: 'sprintf',
-											sprintf: ['@', '#', '@john', '#general'],
-										}),
+										__html: DOMPurify.sanitize(
+											t('Start_with_s_for_user_or_s_for_channel_Eg_s_or_s', {
+												postProcess: 'sprintf',
+												sprintf: ['@', '#', '@john', '#general'],
+											}),
+										),
 									}}
 								/>
 							</Field>
@@ -359,7 +367,7 @@ const OutgoingWebhookForm = () => {
 							<FieldHint id={`${emojiField}-hint-1`}>{t('You_can_use_an_emoji_as_avatar')}</FieldHint>
 							<FieldHint
 								id={`${emojiField}-hint-2`}
-								dangerouslySetInnerHTML={{ __html: t('Example_s', { postProcess: 'sprintf', sprintf: [':ghost:'] }) }}
+								dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Example_s', { postProcess: 'sprintf', sprintf: [':ghost:'] })) }}
 							/>
 						</Field>
 						<Field>
@@ -435,7 +443,7 @@ const OutgoingWebhookForm = () => {
 							<FieldRow>
 								<Box fontScale='p2' withRichContent flexGrow={1}>
 									<pre>
-										<code dangerouslySetInnerHTML={{ __html: hilightedExampleJson }}></code>
+										<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(hilightedExampleJson) }}></code>
 									</pre>
 								</Box>
 							</FieldRow>
@@ -485,7 +493,10 @@ const OutgoingWebhookForm = () => {
 									)}
 								/>
 							</FieldRow>
-							<FieldHint id={`${retryDelayField}-hint`} dangerouslySetInnerHTML={{ __html: t('Integration_Retry_Delay_Description') }} />
+							<FieldHint
+								id={`${retryDelayField}-hint`}
+								dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Integration_Retry_Delay_Description')) }}
+							/>
 						</Field>
 						{event === 'sendMessage' && (
 							<FieldGroup>
diff --git a/apps/meteor/client/views/admin/integrations/outgoing/history/HistoryItem.tsx b/apps/meteor/client/views/admin/integrations/outgoing/history/HistoryItem.tsx
index f016ce36fe7c0..d9581600110c8 100644
--- a/apps/meteor/client/views/admin/integrations/outgoing/history/HistoryItem.tsx
+++ b/apps/meteor/client/views/admin/integrations/outgoing/history/HistoryItem.tsx
@@ -2,6 +2,7 @@ import type { IIntegrationHistory, Serialized } from '@rocket.chat/core-typings'
 import { Button, Icon, Box, AccordionItem, Field, FieldGroup, FieldLabel, FieldRow } from '@rocket.chat/fuselage';
 import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
 import { useMethod } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { useTranslation } from 'react-i18next';
 
 import { outgoingEvents } from '../../../../../../app/integrations/lib/outgoingEvents';
@@ -110,7 +111,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: dataSentToTriggerCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(dataSentToTriggerCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
@@ -122,7 +123,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: prepareSentMessageCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(prepareSentMessageCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
@@ -134,7 +135,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: processSentMessageCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(processSentMessageCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
@@ -156,7 +157,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: httpCallDataCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(httpCallDataCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
@@ -168,7 +169,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: httpErrorCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(httpErrorCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
@@ -180,7 +181,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: httpResultCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(httpResultCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
@@ -192,7 +193,7 @@ const HistoryItem = ({ data }: { data: Serialized<IIntegrationHistory> }) => {
 						<FieldRow>
 							<Box withRichContent w='full'>
 								<pre>
-									<code dangerouslySetInnerHTML={{ __html: errorStackCode }}></code>
+									<code dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(errorStackCode) }}></code>
 								</pre>
 							</Box>
 						</FieldRow>
diff --git a/apps/meteor/client/views/admin/mailer/MailerPage.tsx b/apps/meteor/client/views/admin/mailer/MailerPage.tsx
index 9f6942368faa7..1a38a80c5d2cc 100644
--- a/apps/meteor/client/views/admin/mailer/MailerPage.tsx
+++ b/apps/meteor/client/views/admin/mailer/MailerPage.tsx
@@ -15,6 +15,7 @@ import {
 import { useUniqueId } from '@rocket.chat/fuselage-hooks';
 import { useEndpoint, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
 import { useMutation } from '@tanstack/react-query';
+import DOMPurify from 'dompurify';
 import { Controller, useForm } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
 
@@ -175,7 +176,7 @@ const MailerPage = () => {
 									{errors.emailBody.message}
 								</FieldError>
 							)}
-							<FieldHint id={`${emailBodyId}-hint`} dangerouslySetInnerHTML={{ __html: t('Mailer_body_tags') }} />
+							<FieldHint id={`${emailBodyId}-hint`} dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Mailer_body_tags')) }} />
 						</Field>
 					</FieldGroup>
 				</Box>
diff --git a/apps/meteor/client/views/admin/settings/Setting/Setting.tsx b/apps/meteor/client/views/admin/settings/Setting/Setting.tsx
index 9fb0a5317b053..484eb34cacfa3 100644
--- a/apps/meteor/client/views/admin/settings/Setting/Setting.tsx
+++ b/apps/meteor/client/views/admin/settings/Setting/Setting.tsx
@@ -3,6 +3,7 @@ import { isSettingColor, isSetting } from '@rocket.chat/core-typings';
 import { Box, Button, Tag } from '@rocket.chat/fuselage';
 import { useDebouncedCallback } from '@rocket.chat/fuselage-hooks';
 import { useSettingStructure } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { useEffect, useMemo, useState, useCallback } from 'react';
 import { useTranslation } from 'react-i18next';
@@ -108,7 +109,8 @@ function Setting({ className = undefined, settingId, sectionChanged }: SettingPr
 	);
 
 	const callout = useMemo(
-		() => alert && <span dangerouslySetInnerHTML={{ __html: i18n.exists(alert) ? t(alert) : alert }} />,
+		() =>
+			alert && <span dangerouslySetInnerHTML={{ __html: i18n.exists(alert) ? DOMPurify.sanitize(t(alert)) : DOMPurify.sanitize(alert) }} />,
 		[alert, i18n, t],
 	);
 
diff --git a/apps/meteor/client/views/admin/settings/groups/OAuthGroupPage/OAuthGroupPage.tsx b/apps/meteor/client/views/admin/settings/groups/OAuthGroupPage/OAuthGroupPage.tsx
index 50f523571a0e5..0bfb6a8101a2c 100644
--- a/apps/meteor/client/views/admin/settings/groups/OAuthGroupPage/OAuthGroupPage.tsx
+++ b/apps/meteor/client/views/admin/settings/groups/OAuthGroupPage/OAuthGroupPage.tsx
@@ -2,6 +2,7 @@ import type { ISetting } from '@rocket.chat/core-typings';
 import { Button } from '@rocket.chat/fuselage';
 import { capitalize } from '@rocket.chat/string-helpers';
 import { useToastMessageDispatch, useAbsoluteUrl, useMethod, useTranslation, useSetModal } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { memo, useEffect, useState } from 'react';
 
@@ -118,7 +119,7 @@ function OAuthGroupPage({ _id, onClickBack, ...group }: OAuthGroupPageProps): Re
 							help={
 								<span
 									dangerouslySetInnerHTML={{
-										__html: t('Custom_oauth_helper', callbackURL(sectionName)),
+										__html: DOMPurify.sanitize(t('Custom_oauth_helper', callbackURL(sectionName))),
 									}}
 								/>
 							}
diff --git a/apps/meteor/client/views/admin/users/AdminUserForm.tsx b/apps/meteor/client/views/admin/users/AdminUserForm.tsx
index 1ba9cb3ced5aa..fea907c0719c1 100644
--- a/apps/meteor/client/views/admin/users/AdminUserForm.tsx
+++ b/apps/meteor/client/views/admin/users/AdminUserForm.tsx
@@ -30,6 +30,7 @@ import {
 	useTranslation,
 } from '@rocket.chat/ui-contexts';
 import { useMutation, useQueryClient } from '@tanstack/react-query';
+import DOMPurify from 'dompurify';
 import { useMemo, useState } from 'react';
 import { Controller, useForm } from 'react-hook-form';
 
@@ -270,13 +271,15 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD
 								{isVerificationNeeded && !isSmtpEnabled && (
 									<FieldHint
 										id={`${verifiedId}-hint`}
-										dangerouslySetInnerHTML={{ __html: t('Send_Email_SMTP_Warning', { url: 'admin/settings/Email' }) }}
+										dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Send_Email_SMTP_Warning', { url: 'admin/settings/Email' })) }}
 									/>
 								)}
 								{!isVerificationNeeded && (
 									<FieldHint
 										id={`${verifiedId}-hint`}
-										dangerouslySetInnerHTML={{ __html: t('Email_verification_isnt_required', { url: 'admin/settings/Accounts' }) }}
+										dangerouslySetInnerHTML={{
+											__html: DOMPurify.sanitize(t('Email_verification_isnt_required', { url: 'admin/settings/Accounts' })),
+										}}
 									/>
 								)}
 							</>
@@ -429,7 +432,7 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD
 								{!isSmtpEnabled && (
 									<FieldHint
 										id={`${sendWelcomeEmailId}-hint`}
-										dangerouslySetInnerHTML={{ __html: t('Send_Email_SMTP_Warning', { url: 'admin/settings/Email' }) }}
+										dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Send_Email_SMTP_Warning', { url: 'admin/settings/Email' })) }}
 										mbs={0}
 									/>
 								)}
diff --git a/apps/meteor/client/views/admin/users/AdminUserSetRandomPasswordRadios.tsx b/apps/meteor/client/views/admin/users/AdminUserSetRandomPasswordRadios.tsx
index 7b06f59307221..aa47bc24b67fc 100644
--- a/apps/meteor/client/views/admin/users/AdminUserSetRandomPasswordRadios.tsx
+++ b/apps/meteor/client/views/admin/users/AdminUserSetRandomPasswordRadios.tsx
@@ -1,5 +1,6 @@
 import { Box, FieldHint, FieldLabel, FieldRow, RadioButton } from '@rocket.chat/fuselage';
 import { useUniqueId } from '@rocket.chat/fuselage-hooks';
+import DOMPurify from 'dompurify';
 import type { Control, UseFormSetValue } from 'react-hook-form';
 import { Controller } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
@@ -58,7 +59,7 @@ const AdminUserSetRandomPasswordRadios = ({
 			{!isSmtpEnabled && (
 				<FieldHint
 					id={`${setRandomPasswordId}-hint`}
-					dangerouslySetInnerHTML={{ __html: t('Send_Email_SMTP_Warning', { url: 'admin/settings/Email' }) }}
+					dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('Send_Email_SMTP_Warning', { url: 'admin/settings/Email' })) }}
 					mbe={16}
 					mbs={0}
 				/>
diff --git a/apps/meteor/client/views/banners/LegacyBanner.tsx b/apps/meteor/client/views/banners/LegacyBanner.tsx
index aaf947d195ae1..1227a2a2f8317 100644
--- a/apps/meteor/client/views/banners/LegacyBanner.tsx
+++ b/apps/meteor/client/views/banners/LegacyBanner.tsx
@@ -1,4 +1,5 @@
 import { Banner, Icon } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import { useCallback, useEffect } from 'react';
 
 import type { LegacyBannerPayload } from '../../lib/banners';
@@ -50,7 +51,9 @@ const LegacyBanner = ({ config }: LegacyBannerProps) => {
 			onClose={handleClose}
 		>
 			{typeof text === 'function' ? text() : text}
-			{html && <div dangerouslySetInnerHTML={{ __html: typeof html === 'function' ? html() : html }} />}
+			{html && (
+				<div dangerouslySetInnerHTML={{ __html: typeof html === 'function' ? DOMPurify.sanitize(html()) : DOMPurify.sanitize(html) }} />
+			)}
 		</Banner>
 	);
 };
diff --git a/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx b/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx
index 22c54d7b9eda5..e0ae6fad46113 100644
--- a/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx
+++ b/apps/meteor/client/views/composer/EmojiPicker/EmojiElement.tsx
@@ -1,5 +1,6 @@
 import { css } from '@rocket.chat/css-in-js';
 import { IconButton } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import type { MouseEvent, AllHTMLAttributes } from 'react';
 import { memo } from 'react';
 
@@ -26,7 +27,7 @@ const EmojiElement = ({ emoji, image, onClick, small = false, ...props }: EmojiE
 		}
 	`;
 
-	const emojiElement = <div dangerouslySetInnerHTML={{ __html: image }} />;
+	const emojiElement = <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(image) }} />;
 
 	return (
 		<IconButton
diff --git a/apps/meteor/client/views/composer/EmojiPicker/ToneSelector/ToneItem.tsx b/apps/meteor/client/views/composer/EmojiPicker/ToneSelector/ToneItem.tsx
index 65813965ba04d..35251b7ce6461 100644
--- a/apps/meteor/client/views/composer/EmojiPicker/ToneSelector/ToneItem.tsx
+++ b/apps/meteor/client/views/composer/EmojiPicker/ToneSelector/ToneItem.tsx
@@ -1,4 +1,5 @@
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 
 const ToneItem = ({ tone }: { tone: number }) => {
 	let toneEmoji;
@@ -23,7 +24,7 @@ const ToneItem = ({ tone }: { tone: number }) => {
 			toneEmoji = '<span class="emojione emojione-people _270b">✋</span>';
 	}
 
-	return <Box dangerouslySetInnerHTML={{ __html: toneEmoji }} />;
+	return <Box dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(toneEmoji) }} />;
 };
 
 export default ToneItem;
diff --git a/apps/meteor/client/views/e2e/EnterE2EPasswordModal.tsx b/apps/meteor/client/views/e2e/EnterE2EPasswordModal.tsx
index 8227cd6da79ef..888afa1d7b3e6 100644
--- a/apps/meteor/client/views/e2e/EnterE2EPasswordModal.tsx
+++ b/apps/meteor/client/views/e2e/EnterE2EPasswordModal.tsx
@@ -1,5 +1,6 @@
 import { Box, PasswordInput, Field, FieldGroup, FieldRow, FieldError } from '@rocket.chat/fuselage';
 import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
+import DOMPurify from 'dompurify';
 import type { ChangeEvent, ReactElement } from 'react';
 import { useState, useCallback } from 'react';
 import { useTranslation } from 'react-i18next';
@@ -48,7 +49,7 @@ const EnterE2EPasswordModal = ({
 			onClose={onClose}
 			onCancel={onCancel}
 		>
-			<Box dangerouslySetInnerHTML={{ __html: t('E2E_password_request_text') }} />
+			<Box dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('E2E_password_request_text')) }} />
 			<FieldGroup mbs={24} w='full'>
 				<Field>
 					<FieldRow>
diff --git a/apps/meteor/client/views/e2e/SaveE2EPasswordModal.tsx b/apps/meteor/client/views/e2e/SaveE2EPasswordModal.tsx
index c9e7fa1a8abec..1511b71686d5f 100644
--- a/apps/meteor/client/views/e2e/SaveE2EPasswordModal.tsx
+++ b/apps/meteor/client/views/e2e/SaveE2EPasswordModal.tsx
@@ -1,6 +1,7 @@
 import { Box, CodeSnippet } from '@rocket.chat/fuselage';
 import { useClipboard } from '@rocket.chat/fuselage-hooks';
 import { ExternalLink } from '@rocket.chat/ui-client';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { useTranslation } from 'react-i18next';
 
@@ -31,7 +32,7 @@ const SaveE2EPasswordModal = ({ randomPassword, onClose, onCancel, onConfirm }:
 			annotation={t('You_can_do_from_account_preferences')}
 		>
 			<p>
-				<span dangerouslySetInnerHTML={{ __html: t('E2E_password_reveal_text', { randomPassword }) }} />
+				<span dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('E2E_password_reveal_text', { randomPassword })) }} />
 				<ExternalLink to={DOCS_URL} mis={4}>
 					{t('Learn_more_about_E2EE')}
 				</ExternalLink>
diff --git a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogsItemEntry.tsx b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogsItemEntry.tsx
index 91c18baa01d16..1743fa6013e7e 100644
--- a/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogsItemEntry.tsx
+++ b/apps/meteor/client/views/marketplace/AppDetailsPage/tabs/AppLogs/AppLogsItemEntry.tsx
@@ -1,4 +1,5 @@
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import { useTranslation } from 'react-i18next';
 
 import { useHighlightedCode } from '../../../../../hooks/useHighlightedCode';
@@ -22,7 +23,7 @@ const AppLogsItemEntry = ({ severity, timestamp, caller, args }: AppLogsItemEntr
 				<pre>
 					<code
 						dangerouslySetInnerHTML={{
-							__html: useHighlightedCode('json', JSON.stringify(args, null, 2)),
+							__html: DOMPurify.sanitize(useHighlightedCode('json', JSON.stringify(args, null, 2))),
 						}}
 					/>
 				</pre>
diff --git a/apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearchForm.tsx b/apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearchForm.tsx
index 1da4c0c4a9789..e409df9ee677c 100644
--- a/apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearchForm.tsx
+++ b/apps/meteor/client/views/room/contextualBar/MessageSearchTab/components/MessageSearchForm.tsx
@@ -2,6 +2,7 @@ import type { IMessageSearchProvider } from '@rocket.chat/core-typings';
 import { Box, Field, FieldLabel, FieldHint, Icon, TextInput, ToggleSwitch, Callout } from '@rocket.chat/fuselage';
 import { useDebouncedCallback, useEffectEvent, useUniqueId } from '@rocket.chat/fuselage-hooks';
 import type { TranslationKey } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import { useEffect } from 'react';
 import { useForm, useWatch } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
@@ -57,7 +58,9 @@ const MessageSearchForm = ({ provider, onSearch }: MessageSearchFormProps) => {
 					autoComplete='off'
 					{...register('searchText')}
 				/>
-				{provider.description && <FieldHint dangerouslySetInnerHTML={{ __html: t(provider.description as TranslationKey) }} />}
+				{provider.description && (
+					<FieldHint dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t(provider.description as TranslationKey)) }} />
+				)}
 			</Field>
 			{globalSearchEnabled && (
 				<Field>
diff --git a/apps/meteor/tests/end-to-end/api/oauthapps.ts b/apps/meteor/tests/end-to-end/api/oauthapps.ts
index 5e42069d99341..39fa944223475 100644
--- a/apps/meteor/tests/end-to-end/api/oauthapps.ts
+++ b/apps/meteor/tests/end-to-end/api/oauthapps.ts
@@ -50,79 +50,6 @@ describe('[OAuthApps]', () => {
 		});
 	});
 
-	describe('[/oauth-apps.get]', () => {
-		before(() => updatePermission('manage-oauth-apps', ['admin']));
-		after(() => updatePermission('manage-oauth-apps', ['admin']));
-
-		it('should return a single oauthApp by id', () => {
-			return request
-				.get(api('oauth-apps.get'))
-				.query({ appId: 'zapier' })
-				.set(credentials)
-				.expect(200)
-				.expect((res) => {
-					expect(res.body).to.have.property('success', true);
-					expect(res.body).to.have.property('oauthApp');
-					expect(res.body.oauthApp._id).to.be.equal('zapier');
-					expect(res.body.oauthApp).to.have.property('clientSecret');
-				});
-		});
-		it('should return a single oauthApp by client id', () => {
-			return request
-				.get(api('oauth-apps.get'))
-				.query({ clientId: 'zapier' })
-				.set(credentials)
-				.expect(200)
-				.expect((res) => {
-					expect(res.body).to.have.property('success', true);
-					expect(res.body).to.have.property('oauthApp');
-					expect(res.body.oauthApp._id).to.be.equal('zapier');
-					expect(res.body.oauthApp).to.have.property('clientSecret');
-				});
-		});
-		it('should return only non sensitive information if user does not have the permission to manage oauth apps when searching by clientId', async () => {
-			await updatePermission('manage-oauth-apps', []);
-			await request
-				.get(api('oauth-apps.get'))
-				.query({ clientId: 'zapier' })
-				.set(credentials)
-				.expect(200)
-				.expect((res) => {
-					expect(res.body).to.have.property('success', true);
-					expect(res.body).to.have.property('oauthApp');
-					expect(res.body.oauthApp._id).to.be.equal('zapier');
-					expect(res.body.oauthApp.clientId).to.be.equal('zapier');
-					expect(res.body.oauthApp).to.not.have.property('clientSecret');
-				});
-		});
-		it('should return only non sensitive information if user does not have the permission to manage oauth apps when searching by appId', async () => {
-			await updatePermission('manage-oauth-apps', []);
-			await request
-				.get(api('oauth-apps.get'))
-				.query({ appId: 'zapier' })
-				.set(credentials)
-				.expect(200)
-				.expect((res) => {
-					expect(res.body).to.have.property('success', true);
-					expect(res.body).to.have.property('oauthApp');
-					expect(res.body.oauthApp._id).to.be.equal('zapier');
-					expect(res.body.oauthApp.clientId).to.be.equal('zapier');
-					expect(res.body.oauthApp).to.not.have.property('clientSecret');
-				});
-		});
-		it('should fail returning an oauth app when an invalid id is provided (avoid NoSQL injections)', () => {
-			return request
-				.get(api('oauth-apps.get'))
-				.query({ _id: '{ "$ne": "" }' })
-				.set(credentials)
-				.expect(400)
-				.expect((res) => {
-					expect(res.body).to.have.property('success', false);
-					expect(res.body).to.have.property('error', 'OAuth app not found.');
-				});
-		});
-	});
-
 	describe('[/oauth-apps.create]', () => {
 		it('should return an error when the user does not have the necessary permission', async () => {
 			await updatePermission('manage-oauth-apps', []);
@@ -220,6 +147,213 @@ describe('[OAuthApps]', () => {
 		});
 	});
 
+	describe('[/oauth-apps.get]', () => {
+		let clientId = '';
+		let _id = '';
+		let clientSecret = '';
+
+		before(async () => {
+			await updatePermission('manage-oauth-apps', ['admin']);
+
+			const res = await request
+				.post(api('oauth-apps.create'))
+				.set(credentials)
+				.send({
+					name: `new app ${Date.now()}`,
+					redirectUri: 'http://localhost:3000',
+					active: true,
+				});
+
+			if (res.statusCode !== 200 || !res.body?.success || !res.body.application?._id || !res.body.application?.clientId) {
+				console.error(res);
+				throw new Error('Failed to create oauth app for tests');
+			}
+
+			clientId = res.body.application.clientId;
+			_id = res.body.application._id;
+			clientSecret = res.body.application.clientSecret;
+			createdAppsIds.push(_id);
+		});
+		after(() => updatePermission('manage-oauth-apps', ['admin']));
+
+		it('should return a single oauthApp by client id', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ clientId })
+				.set(credentials)
+				.expect(200)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', true);
+					expect(res.body).to.have.property('oauthApp');
+					expect(res.body.oauthApp._id).to.be.equal(_id);
+					expect(res.body.oauthApp).to.have.property('clientSecret');
+
+					if (clientSecret) {
+						expect(res.body.oauthApp.clientSecret).to.be.equal(clientSecret);
+					}
+				});
+		});
+
+		it('should return a single oauthApp by _id', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ _id })
+				.set(credentials)
+				.expect(200)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', true);
+					expect(res.body).to.have.property('oauthApp');
+					expect(res.body.oauthApp._id).to.be.equal(_id);
+					expect(res.body.oauthApp.clientId).to.be.equal(clientId);
+					expect(res.body.oauthApp).to.have.property('clientSecret');
+					if (clientSecret) {
+						expect(res.body.oauthApp.clientSecret).to.be.equal(clientSecret);
+					}
+				});
+		});
+
+		it('should return a single oauthApp by appId (deprecated)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ appId: _id })
+				.set(credentials)
+				.expect(200)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', true);
+					expect(res.body).to.have.property('oauthApp');
+					expect(res.body.oauthApp._id).to.be.equal(_id);
+					expect(res.body.oauthApp.clientId).to.be.equal(clientId);
+					expect(res.body.oauthApp).to.have.property('clientSecret');
+					if (clientSecret) {
+						expect(res.body.oauthApp.clientSecret).to.be.equal(clientSecret);
+					}
+				});
+		});
+
+		it('should return only non sensitive information if user does not have the permission to manage oauth apps when searching by clientId', async () => {
+			await updatePermission('manage-oauth-apps', []);
+			await request
+				.get(api('oauth-apps.get'))
+				.query({ clientId })
+				.set(credentials)
+				.expect(200)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', true);
+					expect(res.body).to.have.property('oauthApp');
+					expect(res.body.oauthApp._id).to.be.equal(_id);
+					expect(res.body.oauthApp.clientId).to.be.equal(clientId);
+					expect(res.body.oauthApp).to.not.have.property('clientSecret');
+				});
+		});
+
+		it('should return only non sensitive information if user does not have the permission to manage oauth apps when searching by _id', async () => {
+			await updatePermission('manage-oauth-apps', []);
+			await request
+				.get(api('oauth-apps.get'))
+				.query({ _id })
+				.set(credentials)
+				.expect(200)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', true);
+					expect(res.body).to.have.property('oauthApp');
+					expect(res.body.oauthApp._id).to.be.equal(_id);
+					expect(res.body.oauthApp.clientId).to.be.equal(clientId);
+					expect(res.body.oauthApp).to.not.have.property('clientSecret');
+				});
+		});
+
+		it('should return only non sensitive information if user does not have the permission to manage oauth apps when searching by appId (deprecated)', async () => {
+			await updatePermission('manage-oauth-apps', []);
+			await request
+				.get(api('oauth-apps.get'))
+				.query({ appId: _id })
+				.set(credentials)
+				.expect(200)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', true);
+					expect(res.body).to.have.property('oauthApp');
+					expect(res.body.oauthApp._id).to.be.equal(_id);
+					expect(res.body.oauthApp.clientId).to.be.equal(clientId);
+					expect(res.body.oauthApp).to.not.have.property('clientSecret');
+				});
+		});
+
+		it('should fail returning an oauth app when an invalid id is provided (avoid NoSQL injections)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ _id: { $ne: '' } })
+				.set(credentials)
+				.expect(400)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', false);
+					expect(res.body).to.have.property('error');
+					expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf [invalid-params]');
+				});
+		});
+
+		it('should fail returning an oauth app when an invalid id string is provided (avoid NoSQL injections)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ _id: '{ "$ne": "" }' })
+				.set(credentials)
+				.expect(400)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', false);
+					expect(res.body).to.have.property('error', 'OAuth app not found.');
+				});
+		});
+
+		it('should fail returning an oauth app when an invalid clientId is provided (avoid NoSQL injections)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ clientId: { $ne: '' } })
+				.set(credentials)
+				.expect(400)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', false);
+					expect(res.body).to.have.property('error');
+					expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf [invalid-params]');
+				});
+		});
+
+		it('should fail returning an oauth app when an invalid clientId string is provided (avoid NoSQL injections)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ clientId: '{ "$ne": "" }' })
+				.set(credentials)
+				.expect(400)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', false);
+					expect(res.body).to.have.property('error', 'OAuth app not found.');
+				});
+		});
+
+		it('should fail returning an oauth app when an invalid appId is provided (avoid NoSQL injections; deprecated)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ appId: { $ne: '' } })
+				.set(credentials)
+				.expect(400)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', false);
+					expect(res.body).to.have.property('error');
+					expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf [invalid-params]');
+				});
+		});
+
+		it('should fail returning an oauth app when an invalid appId string is provided (avoid NoSQL injections; deprecated)', () => {
+			return request
+				.get(api('oauth-apps.get'))
+				.query({ appId: '{ "$ne": "" }' })
+				.set(credentials)
+				.expect(400)
+				.expect((res) => {
+					expect(res.body).to.have.property('success', false);
+					expect(res.body).to.have.property('error', 'OAuth app not found.');
+				});
+		});
+	});
+
 	describe('[/oauth-apps.update]', () => {
 		let appId: IOAuthApps['_id'];
 
diff --git a/packages/apps-engine/deno-runtime/lib/accessors/modify/ModifyCreator.ts b/packages/apps-engine/deno-runtime/lib/accessors/modify/ModifyCreator.ts
index 00b4640295e51..f4509990edc99 100644
--- a/packages/apps-engine/deno-runtime/lib/accessors/modify/ModifyCreator.ts
+++ b/packages/apps-engine/deno-runtime/lib/accessors/modify/ModifyCreator.ts
@@ -17,6 +17,7 @@ import type { ILivechatMessageBuilder } from '@rocket.chat/apps-engine/definitio
 import type { UIHelper as _UIHelper } from '@rocket.chat/apps-engine/server/misc/UIHelper.ts';
 
 import * as Messenger from '../../messenger.ts';
+import { randomBytes } from 'node:crypto';
 
 import { BlockBuilder } from '../builders/BlockBuilder.ts';
 import { MessageBuilder } from '../builders/MessageBuilder.ts';
@@ -45,7 +46,7 @@ export class ModifyCreator implements IModifyCreator {
                 get: (_target: unknown, prop: string) => {
                     // It's not worthwhile to make an asynchronous request for such a simple method
                     if (prop === 'createToken') {
-                        return () => Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
+                        return () => randomBytes(16).toString('hex');
                     }
 
                     if (prop === 'toJSON') {
diff --git a/packages/apps-engine/src/server/accessors/LivechatCreator.ts b/packages/apps-engine/src/server/accessors/LivechatCreator.ts
index 0462230b97b04..b0cfbf5be4810 100644
--- a/packages/apps-engine/src/server/accessors/LivechatCreator.ts
+++ b/packages/apps-engine/src/server/accessors/LivechatCreator.ts
@@ -1,3 +1,5 @@
+import { randomBytes } from 'crypto';
+
 import type { ILivechatCreator } from '../../definition/accessors';
 import type { IExtraRoomParams } from '../../definition/accessors/ILivechatCreator';
 import type { ILivechatRoom } from '../../definition/livechat/ILivechatRoom';
@@ -27,6 +29,6 @@ export class LivechatCreator implements ILivechatCreator {
     }
 
     public createToken(): string {
-        return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
+        return randomBytes(16).toString('hex'); // Ensures 128 bits of entropy
     }
 }
diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json
index 93ea90a09a3c5..f376a986ae8af 100644
--- a/packages/i18n/src/locales/en.i18n.json
+++ b/packages/i18n/src/locales/en.i18n.json
@@ -5513,7 +5513,9 @@
   "This_is_a_desktop_notification": "This is a desktop notification",
   "This_is_a_deprecated_feature_alert": "This is a deprecated feature. It may not work as expected and will not get new updates.",
   "Zapier_integration_has_been_deprecated": "The Zapier integration has been deprecated, may not work as expected and will not receive updates",
+  "Zapier_integration_is_not_available": "The Zapier integration has been deprecated and is no longer available for new Rocket.Chat workspaces",
   "Install_Zapier_from_marketplace": "Install the Zapier app from Marketplace to avoid disruptions",
+  "Install_Zapier_from_marketplace_new_workspaces": "Install the Zapier app from Marketplace to configure new integrations",
   "Input": "Input",
   "This_is_a_push_test_messsage": "This is a push test message",
   "This_message_was_rejected_by__peer__peer": "This message was rejected by <em>{{peer}}</em> peer.",
diff --git a/packages/ui-client/package.json b/packages/ui-client/package.json
index a8587428ef527..ef0602ab7e753 100644
--- a/packages/ui-client/package.json
+++ b/packages/ui-client/package.json
@@ -38,6 +38,7 @@
 		"@storybook/react": "^8.4.4",
 		"@storybook/react-webpack5": "^8.4.4",
 		"@testing-library/react": "~16.0.1",
+		"@types/dompurify": "^3.0.5",
 		"@types/jest": "~29.5.14",
 		"@types/react": "~17.0.83",
 		"@types/react-dom": "~17.0.26",
@@ -67,5 +68,8 @@
 	},
 	"volta": {
 		"extends": "../../package.json"
+	},
+	"dependencies": {
+		"dompurify": "^3.2.0"
 	}
 }
diff --git a/packages/ui-client/src/components/EmojiPicker/EmojiPickerPreview.tsx b/packages/ui-client/src/components/EmojiPicker/EmojiPickerPreview.tsx
index dd6a15a468b0e..332f6c831f55e 100644
--- a/packages/ui-client/src/components/EmojiPicker/EmojiPickerPreview.tsx
+++ b/packages/ui-client/src/components/EmojiPicker/EmojiPickerPreview.tsx
@@ -1,5 +1,6 @@
 import { css } from '@rocket.chat/css-in-js';
 import { Box } from '@rocket.chat/fuselage';
+import DOMPurify from 'dompurify';
 import type { AllHTMLAttributes } from 'react';
 
 const EmojiPickerPreview = ({ emoji, name, ...props }: { emoji: string; name: string } & Omit<AllHTMLAttributes<HTMLDivElement>, 'is'>) => {
@@ -12,7 +13,7 @@ const EmojiPickerPreview = ({ emoji, name, ...props }: { emoji: string; name: st
 
 	return (
 		<Box {...props} display='flex' alignItems='center'>
-			<Box className={previewEmojiClass} dangerouslySetInnerHTML={{ __html: emoji }}></Box>
+			<Box className={previewEmojiClass} dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(emoji) }}></Box>
 			<Box mis={4} display='flex' flexDirection='column' maxWidth='x160'>
 				<Box fontScale='c2' withTruncatedText>
 					{name}
diff --git a/packages/web-ui-registration/package.json b/packages/web-ui-registration/package.json
index 028983ac29fee..720b698ceda9a 100644
--- a/packages/web-ui-registration/package.json
+++ b/packages/web-ui-registration/package.json
@@ -36,6 +36,7 @@
 		"@storybook/theming": "^8.4.4",
 		"@tanstack/react-query": "patch:@tanstack/react-query@npm%3A5.60.5#~/.yarn/patches/@tanstack-react-query-npm-5.60.5-04c500b172.patch",
 		"@testing-library/react": "~16.0.1",
+		"@types/dompurify": "^3.0.5",
 		"@types/react": "~17.0.83",
 		"babel-loader": "~9.2.1",
 		"eslint": "~8.45.0",
@@ -57,5 +58,8 @@
 	},
 	"volta": {
 		"extends": "../../package.json"
+	},
+	"dependencies": {
+		"dompurify": "^3.2.0"
 	}
 }
diff --git a/packages/web-ui-registration/src/components/LoginTerms.tsx b/packages/web-ui-registration/src/components/LoginTerms.tsx
index 67dc916fec2d4..d582e0e7321c8 100644
--- a/packages/web-ui-registration/src/components/LoginTerms.tsx
+++ b/packages/web-ui-registration/src/components/LoginTerms.tsx
@@ -1,6 +1,7 @@
 import { Box } from '@rocket.chat/fuselage';
 import { HorizontalWizardLayoutCaption } from '@rocket.chat/layout';
 import { useSetting } from '@rocket.chat/ui-contexts';
+import DOMPurify from 'dompurify';
 import type { ReactElement } from 'react';
 import { useTranslation } from 'react-i18next';
 
@@ -10,7 +11,12 @@ export const LoginTerms = (): ReactElement => {
 
 	return (
 		<HorizontalWizardLayoutCaption>
-			<Box withRichContent dangerouslySetInnerHTML={{ __html: loginTerms !== '' ? loginTerms : t('Layout_Login_Terms_Content') }} />
+			<Box
+				withRichContent
+				dangerouslySetInnerHTML={{
+					__html: loginTerms !== '' ? DOMPurify.sanitize(loginTerms) : DOMPurify.sanitize(t('Layout_Login_Terms_Content')),
+				}}
+			/>
 		</HorizontalWizardLayoutCaption>
 	);
 };