From f574d8cc2455e9bbfd0e55f2dad475a4bbe70016 Mon Sep 17 00:00:00 2001 From: yasnagat Date: Tue, 24 Feb 2026 14:37:07 -0300 Subject: [PATCH 1/5] fix: add validation for SAML SLO redirect URLs --- .../meteor-accounts-saml/server/lib/SAML.ts | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts index fdac8b0b77fa8..88e188de08028 100644 --- a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts +++ b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts @@ -74,7 +74,7 @@ export class SAML { case 'logout': return this.processLogoutAction(req, res, service); case 'sloRedirect': - return this.processSLORedirectAction(req, res); + return this.processSLORedirectAction(req, res, service); case 'authorize': return this.processAuthorizeAction(res, service, samlObject); case 'validate': @@ -391,11 +391,50 @@ export class SAML { }); } - private static processSLORedirectAction(req: IIncomingMessage, res: ServerResponse): void { + private static processSLORedirectAction(req: IIncomingMessage, res: ServerResponse, service: IServiceProviderOptions): void { + const { idpSLORedirectURL } = service; + const userRedirect = req.query.redirect as string; + + if (!idpSLORedirectURL) { + res.writeHead(500); + res.end('SLO redirect not configured'); + return; + } + + if (!userRedirect) { + res.writeHead(400); + res.end('Missing redirect parameter'); + return; + } + + let configuredURL: URL; + let requestURL: URL; + + try { + configuredURL = new URL(idpSLORedirectURL); + requestURL = new URL(userRedirect); + } catch { + res.writeHead(400); + res.end('Invalid URL format'); + return; + } + + if (configuredURL.origin !== requestURL.origin) { + res.writeHead(403); + res.end('Unauthorized redirect origin'); + return; + } + + if (configuredURL.pathname !== requestURL.pathname) { + res.writeHead(403); + res.end('Unauthorized redirect path'); + return; + } + res.writeHead(302, { - // credentialToken here is the SAML LogOut Request that we'll send back to IDP - Location: req.query.redirect, + Location: requestURL.toString(), }); + res.end(); } From fd4998da557c594a178e159162a7f661a25d8a4e Mon Sep 17 00:00:00 2001 From: Yasmim Nagat <117310290+yasnagat@users.noreply.github.com> Date: Fri, 27 Feb 2026 10:29:25 -0300 Subject: [PATCH 2/5] Normalize path comparison for redirect validation --- apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts index 88e188de08028..922507dbbbb70 100644 --- a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts +++ b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts @@ -425,7 +425,8 @@ export class SAML { return; } - if (configuredURL.pathname !== requestURL.pathname) { + const normalizePath = (p: string): string => p.replace(/\/+$/, '') || '/'; + if (normalizePath(configuredURL.pathname) !== normalizePath(requestURL.pathname)) { res.writeHead(403); res.end('Unauthorized redirect path'); return; From 68438669e3f9722eaac99a14f969b3c616928f8e Mon Sep 17 00:00:00 2001 From: Yasmim Nagat <117310290+yasnagat@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:02:55 -0300 Subject: [PATCH 3/5] Update apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts Co-authored-by: Pierre Lehnen <55164754+pierre-lehnen-rc@users.noreply.github.com> --- apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts index 922507dbbbb70..d42e266382186 100644 --- a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts +++ b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts @@ -401,7 +401,7 @@ export class SAML { return; } - if (!userRedirect) { + if (!userRedirect || typeof userRedirect !== 'string') { res.writeHead(400); res.end('Missing redirect parameter'); return; From 568e6c3c2ab2509f7acc74bc8820333df5fb7055 Mon Sep 17 00:00:00 2001 From: yasnagat Date: Wed, 4 Mar 2026 19:34:01 -0300 Subject: [PATCH 4/5] add changeset file --- .changeset/metal-rice-retire.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/metal-rice-retire.md diff --git a/.changeset/metal-rice-retire.md b/.changeset/metal-rice-retire.md new file mode 100644 index 0000000000000..0ed9fb757076e --- /dev/null +++ b/.changeset/metal-rice-retire.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Adds SAML redirect validation by matching request parameters and configured IdP SLO From 3346067b8a0dab52852a2c22af5e744647c55556 Mon Sep 17 00:00:00 2001 From: Julio Araujo Date: Thu, 19 Mar 2026 17:53:23 +0100 Subject: [PATCH 5/5] Update apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts --- apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts index 90c3546d5c147..cac4a5ae0376d 100644 --- a/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts +++ b/apps/meteor/app/meteor-accounts-saml/server/lib/SAML.ts @@ -384,7 +384,7 @@ export class SAML { await logOutUser(inResponseTo); } finally { res.writeHead(302, { - Location: req.query.RelayState, + Location: Meteor.absoluteUrl(), }); res.end(); }