From dd6c49e214b489aed03486440b784d8dfa7fa20c Mon Sep 17 00:00:00 2001 From: Patrick Pimentel Date: Fri, 23 Jan 2026 17:28:17 -0500 Subject: [PATCH] fix(redirect): [PM-30810] Https Redirection for Cloud Users - Added a client check to only allow mobile to specify the extra property being sent to the duo api when generating the token. --- .../DuoUniversalTokenService.cs | 34 ++++++++++++++++--- src/Core/Enums/ClientType.cs | 3 +- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Core/Auth/Identity/TokenProviders/DuoUniversalTokenService.cs b/src/Core/Auth/Identity/TokenProviders/DuoUniversalTokenService.cs index d7ac1e2510..3b23e7ce0f 100644 --- a/src/Core/Auth/Identity/TokenProviders/DuoUniversalTokenService.cs +++ b/src/Core/Auth/Identity/TokenProviders/DuoUniversalTokenService.cs @@ -1,10 +1,12 @@ // FIXME: Update this file to be null safe and then delete the line below #nullable disable +using System.Globalization; using Bit.Core.Auth.Models; using Bit.Core.Auth.Models.Business.Tokenables; using Bit.Core.Context; using Bit.Core.Entities; +using Bit.Core.Enums; using Bit.Core.Settings; using Bit.Core.Tokens; using Microsoft.AspNetCore.Http; @@ -213,11 +215,33 @@ public class DuoUniversalTokenService( // Fetch Client name from header value since duo auth can be initiated from multiple clients and we want // to redirect back to the initiating client _currentContext.HttpContext.Request.Headers.TryGetValue("Bitwarden-Client-Name", out var bitwardenClientName); - var requestHost = _currentContext.HttpContext?.Request?.Host.Host; - var deeplinkScheme = GetDeeplinkSchemeOverride(_currentContext.HttpContext) ?? - (IsBitwardenCloudHost(requestHost) ? "https" : "bitwarden"); - var redirectUri = string.Format("{0}/duo-redirect-connector.html?client={1}&deeplinkScheme={2}", - _globalSettings.BaseServiceUri.Vault, bitwardenClientName.FirstOrDefault() ?? "web", deeplinkScheme); + var clientTypeHeader = bitwardenClientName.FirstOrDefault(); + var clientType = Enum.TryParse(clientTypeHeader, ignoreCase: true, out var parsedClientType) + ? parsedClientType + : ClientType.Web; + var clientName = clientType.ToString().ToLowerInvariant(); + + string redirectUri; + + // Handle mobile case separately because mobile needs to define the scheme ahead of time + // for security reasons. + if (clientType == ClientType.Mobile) + { + var requestHost = _currentContext.HttpContext.Request.Host.Host; + var deeplinkScheme = GetDeeplinkSchemeOverride(_currentContext.HttpContext) ?? + (IsBitwardenCloudHost(requestHost) ? "https" : "bitwarden"); + redirectUri = string.Format(CultureInfo.InvariantCulture, + "{0}/duo-redirect-connector.html?client={1}&deeplinkScheme={2}", + _globalSettings.BaseServiceUri.Vault, clientName, deeplinkScheme); + } + // All other clients will not use the deep link scheme property built into the duo token provided + // back from their api. + else + { + redirectUri = string.Format(CultureInfo.InvariantCulture, + "{0}/duo-redirect-connector.html?client={1}", + _globalSettings.BaseServiceUri.Vault, clientName); + } var client = new Duo.ClientBuilder( (string)provider.MetaData["ClientId"], diff --git a/src/Core/Enums/ClientType.cs b/src/Core/Enums/ClientType.cs index 0e0cfe4b26..1789bbe0c5 100644 --- a/src/Core/Enums/ClientType.cs +++ b/src/Core/Enums/ClientType.cs @@ -1,5 +1,4 @@ -#nullable enable -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; namespace Bit.Core.Enums;