Skip to content

Commit d053d3e

Browse files
fix: harden www redirect against open redirect
1 parent 5f422e0 commit d053d3e

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

EssentialCSharp.Web/Program.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,17 @@ await context.HttpContext.Response.WriteAsync(
430430
// Configure the HTTP request pipeline.
431431
if (!app.Environment.IsDevelopment())
432432
{
433+
SiteSettings siteSettings = app.Services.GetRequiredService<IOptions<SiteSettings>>().Value;
434+
if (!Uri.TryCreate(siteSettings.BaseUrl, UriKind.Absolute, out Uri? configuredBaseUri))
435+
{
436+
throw new InvalidOperationException($"Invalid {SiteSettings.SectionName}:{nameof(SiteSettings.BaseUrl)} value: '{siteSettings.BaseUrl}'.");
437+
}
438+
string apexHost = configuredBaseUri.Host.StartsWith("www.", StringComparison.OrdinalIgnoreCase)
439+
? configuredBaseUri.Host[4..]
440+
: configuredBaseUri.Host;
441+
string wwwHost = $"www.{apexHost}";
442+
string redirectAuthority = new UriBuilder(configuredBaseUri) { Host = apexHost }.Uri.GetLeftPart(UriPartial.Authority);
443+
433444
app.UseExceptionHandler(exceptionApp =>
434445
{
435446
exceptionApp.Run(async context =>
@@ -494,14 +505,13 @@ await McpJsonRpcResponseWriter.WriteErrorAsync(
494505
.AddDefaultSecurePolicy()
495506
.AddContentSecurityPolicy(csp));
496507

497-
// Redirect www.essentialcsharp.com → essentialcsharp.com (permanent 301)
508+
// Redirect configured www host to configured apex host (permanent 301).
498509
// Must be after UseForwardedHeaders so the Host header reflects the real hostname.
499510
app.Use(async (context, next) =>
500511
{
501-
if (context.Request.Host.Host.StartsWith("www.", StringComparison.OrdinalIgnoreCase))
512+
if (string.Equals(context.Request.Host.Host, wwwHost, StringComparison.OrdinalIgnoreCase))
502513
{
503-
string apexHost = context.Request.Host.Host[4..];
504-
string redirectUrl = $"{context.Request.Scheme}://{apexHost}{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}";
514+
string redirectUrl = $"{redirectAuthority}{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}";
505515
context.Response.Redirect(redirectUrl, permanent: true);
506516
return;
507517
}

0 commit comments

Comments
 (0)