From fc74c7bff28f0ad1c6fb1982c6254d4f01dff665 Mon Sep 17 00:00:00 2001 From: Ignacio Inglese Date: Mon, 31 Aug 2026 11:43:20 +0100 Subject: [PATCH] fix: validate Sidecar forwarded header configuration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Microsoft.Identity.Web.Sidecar/Program.cs | 20 +++++- .../Properties/InternalsVisibleTo.cs | 6 ++ .../ForwardedHeadersConfigurationTests.cs | 68 +++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.Identity.Web.Sidecar/Properties/InternalsVisibleTo.cs create mode 100644 tests/E2E Tests/Sidecar.Tests/ForwardedHeadersConfigurationTests.cs diff --git a/src/Microsoft.Identity.Web.Sidecar/Program.cs b/src/Microsoft.Identity.Web.Sidecar/Program.cs index 7fad0e589..70d89c988 100644 --- a/src/Microsoft.Identity.Web.Sidecar/Program.cs +++ b/src/Microsoft.Identity.Web.Sidecar/Program.cs @@ -23,7 +23,7 @@ public static void Main(string[] args) #pragma warning restore IL3057 #pragma warning restore IL2123 { - var builder = WebApplication.CreateSlimBuilder(args); + var builder = CreateBuilder(args); builder.Services.ConfigureHttpJsonOptions(options => { @@ -96,6 +96,24 @@ public static void Main(string[] args) app.Run(); } + internal static WebApplicationBuilder CreateBuilder(string[] args) + { + var builder = WebApplication.CreateSlimBuilder(args); + + if (!builder.Environment.IsDevelopment() && + string.Equals( + builder.Configuration["ForwardedHeaders_Enabled"], + "true", + StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidOperationException( + "Forwarded headers cannot be enabled outside Development. " + + "Remove 'ForwardedHeaders_Enabled' or set it to 'false'."); + } + + return builder; + } + private static void ConfigureAuthN(WebApplicationBuilder builder) { // Disable claims mapping. diff --git a/src/Microsoft.Identity.Web.Sidecar/Properties/InternalsVisibleTo.cs b/src/Microsoft.Identity.Web.Sidecar/Properties/InternalsVisibleTo.cs new file mode 100644 index 000000000..577f0ed2c --- /dev/null +++ b/src/Microsoft.Identity.Web.Sidecar/Properties/InternalsVisibleTo.cs @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Sidecar.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001002D96616729B54F6D013D71559A017F50AA4861487226C523959D1579B93F3FDF71C08B980FD3130062B03D3DE115C4B84E7AC46AEF5E192A40E7457D5F3A08F66CEAB71143807F2C3CB0DA5E23B38F0559769978406F6E5D30CEADD7985FC73A5A609A8B74A1DF0A29399074A003A226C943D480FEC96DBEC7106A87896539AD")] diff --git a/tests/E2E Tests/Sidecar.Tests/ForwardedHeadersConfigurationTests.cs b/tests/E2E Tests/Sidecar.Tests/ForwardedHeadersConfigurationTests.cs new file mode 100644 index 000000000..b3244e87f --- /dev/null +++ b/tests/E2E Tests/Sidecar.Tests/ForwardedHeadersConfigurationTests.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.Extensions.Hosting; +using Microsoft.Identity.Web.Sidecar; +using Xunit; + +namespace Sidecar.Tests; + +public class ForwardedHeadersConfigurationTests +{ + [Theory] + [InlineData("Production", "true")] + [InlineData("Staging", "TrUe")] + public void Startup_ForwardedHeadersEnabledOutsideDevelopment_Throws( + string environmentName, + string value) + { + // Act & Assert + var exception = Assert.Throws(() => + Program.CreateBuilder(CreateArguments(environmentName, value))); + + Assert.Equal( + "Forwarded headers cannot be enabled outside Development. " + + "Remove 'ForwardedHeaders_Enabled' or set it to 'false'.", + exception.Message); + } + + [Theory] + [InlineData(null)] + [InlineData("false")] + [InlineData("enabled")] + [InlineData(" true ")] + public void Startup_ForwardedHeadersNotActivatedOutsideDevelopment_Succeeds(string? value) + { + // Act + var builder = Program.CreateBuilder(CreateArguments("Production", value)); + + // Assert + Assert.Equal("Production", builder.Environment.EnvironmentName); + } + + [Fact] + public void Startup_ForwardedHeadersEnabledInDevelopment_Succeeds() + { + // Act + var builder = Program.CreateBuilder(CreateArguments("Development", "true")); + + // Assert + Assert.True(builder.Environment.IsDevelopment()); + } + + private static string[] CreateArguments(string environmentName, string? value) + { + if (value is null) + { + return ["--environment", environmentName]; + } + + return + [ + "--environment", + environmentName, + "--ForwardedHeaders_Enabled", + value, + ]; + } +}