From 53da3f8687b0fd09fcd3ec8850f81eba4a5eb019 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Tue, 19 May 2026 21:31:47 -0700 Subject: [PATCH 1/2] Use local redirect target for www->apex Build redirect target from PathString/QueryString instead of interpolating an absolute URL with request-derived segments. This preserves permanent redirect behavior while resolving the CodeQL unvalidated URL redirection finding. --- EssentialCSharp.Web/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EssentialCSharp.Web/Program.cs b/EssentialCSharp.Web/Program.cs index 0b2021af..c91efc57 100644 --- a/EssentialCSharp.Web/Program.cs +++ b/EssentialCSharp.Web/Program.cs @@ -453,7 +453,6 @@ await context.HttpContext.Response.WriteAsync( ? configuredBaseUri.Host[4..] : configuredBaseUri.Host; string wwwHost = $"www.{apexHost}"; - string redirectAuthority = new UriBuilder(configuredBaseUri) { Host = apexHost }.Uri.GetLeftPart(UriPartial.Authority); app.UseExceptionHandler(exceptionApp => { @@ -525,8 +524,9 @@ await McpJsonRpcResponseWriter.WriteErrorAsync( { if (string.Equals(context.Request.Host.Host, wwwHost, StringComparison.OrdinalIgnoreCase)) { - string redirectUrl = $"{redirectAuthority}{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}"; - context.Response.Redirect(redirectUrl, permanent: true); + PathString redirectPath = context.Request.PathBase.Add(context.Request.Path); + string redirectTarget = $"{redirectPath}{context.Request.QueryString}"; + context.Response.Redirect(redirectTarget, permanent: true); return; } await next(context); From 0e32533baa593fbfd24fc829bad4a2434f35b1a1 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Tue, 19 May 2026 22:10:09 -0700 Subject: [PATCH 2/2] Fix www redirect canonical host Use UriHelper.BuildAbsolute with configured canonical scheme and apex host while preserving request PathBase/Path/Query for the redirect target. This avoids relative redirect loops and keeps CodeQL-safe construction. --- EssentialCSharp.Web/Program.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/EssentialCSharp.Web/Program.cs b/EssentialCSharp.Web/Program.cs index c91efc57..246b9247 100644 --- a/EssentialCSharp.Web/Program.cs +++ b/EssentialCSharp.Web/Program.cs @@ -15,6 +15,7 @@ using EssentialCSharp.Web.Tools; using Mailjet.Client; using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; @@ -524,8 +525,15 @@ await McpJsonRpcResponseWriter.WriteErrorAsync( { if (string.Equals(context.Request.Host.Host, wwwHost, StringComparison.OrdinalIgnoreCase)) { - PathString redirectPath = context.Request.PathBase.Add(context.Request.Path); - string redirectTarget = $"{redirectPath}{context.Request.QueryString}"; + HostString redirectHost = configuredBaseUri.IsDefaultPort + ? new HostString(apexHost) + : new HostString(apexHost, configuredBaseUri.Port); + string redirectTarget = UriHelper.BuildAbsolute( + configuredBaseUri.Scheme, + redirectHost, + context.Request.PathBase, + context.Request.Path, + context.Request.QueryString); context.Response.Redirect(redirectTarget, permanent: true); return; }