From f4a9324c20c70c79f49db3638b4e99ed76e9269a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 Aug 2025 00:43:28 +0000 Subject: [PATCH 1/4] Initial plan From 95a70ba4f3b9a7d8540301073c72f50a65a017ba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 16 Aug 2025 00:52:58 +0000 Subject: [PATCH 2/4] Add documentation for Forwarded Headers Middleware breaking change in .NET 8 Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- docs/core/compatibility/8.0.md | 1 + .../8.0/forwarded-headers-unknown-proxies.md | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md diff --git a/docs/core/compatibility/8.0.md b/docs/core/compatibility/8.0.md index b475fba01d0bf..6c56c864ba3aa 100644 --- a/docs/core/compatibility/8.0.md +++ b/docs/core/compatibility/8.0.md @@ -17,6 +17,7 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff | ---------------------------------------------------------------------------------------------------- | ------------------- | | [ConcurrencyLimiterMiddleware is obsolete](aspnet-core/8.0/concurrencylimitermiddleware-obsolete.md) | Source incompatible | | [Custom converters for serialization removed](aspnet-core/8.0/problemdetails-custom-converters.md) | Behavioral change | +| [Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies](aspnet-core/8.0/forwarded-headers-unknown-proxies.md) | Behavioral change | | [ISystemClock is obsolete](aspnet-core/8.0/isystemclock-obsolete.md) | Source incompatible | | [Minimal APIs: IFormFile parameters require anti-forgery checks](aspnet-core/8.0/antiforgery-checks.md) | Behavioral change | | [Rate-limiting middleware requires AddRateLimiter](aspnet-core/8.0/addratelimiter-requirement.md) | Behavioral change | diff --git a/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md b/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md new file mode 100644 index 0000000000000..ef0f96d166ace --- /dev/null +++ b/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md @@ -0,0 +1,70 @@ +--- +title: "Breaking change: Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies" +description: Learn about the breaking change in ASP.NET Core 8.0.17 where Forwarded Headers Middleware now ignores headers from proxies that are not explicitly configured as trusted. +ms.date: 01/16/2025 +--- +# Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies + +Starting in ASP.NET Core 8.0.17 and 9.0.6, the Forwarded Headers Middleware ignores all `X-Forwarded-*` headers from proxies that are not explicitly configured as trusted. This change was made for security hardening, as the proxy and IP lists weren't being applied in all cases. + +## Version introduced + +ASP.NET Core 8.0.17 + +## Previous behavior + +Previously, the middleware, when not configured to use `X-Forwarded-For`, would process `X-Forwarded-Prefix`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers from any source, potentially allowing malicious or misconfigured proxies/clients to spoof these headers and affect your application's understanding of client information. + +## New behavior + +With this change, only headers sent by known, trusted proxies (as configured via and ) are processed. Headers from unknown sources are ignored. + +This can cause behavior like infinite redirects if you're using the HTTPS redirection middleware and using TLS termination in your proxy. Or authentication to fail if using TLS termination and expecting an HTTPS request. + +## Type of breaking change + +This change affects [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +The change was made for security hardening, as the proxy and IP lists weren't being applied in all cases. + +## Recommended action + +**Review your deployment topology:** Ensure that all legitimate proxy servers in front of your app are properly added to `KnownProxies` or `KnownNetworks` in your configuration. + +```csharp +app.UseForwardedHeaders(new ForwardedHeadersOptions +{ + KnownProxies = { IPAddress.Parse("YOUR_PROXY_IP") } +}); +``` + +Or, for a network: + +```csharp +app.UseForwardedHeaders(new ForwardedHeadersOptions +{ + KnownNetworks = { new IPNetwork(IPAddress.Parse("YOUR_NETWORK_IP"), PREFIX_LENGTH) } +}); +``` + +**If you wish to enable previous behavior:** You may need to relax your configuration, but this is **not recommended** due to security risks. You can do this by clearing the `KnownNetworks` and `KnownProxies` lists in to allow any proxy or network to forward these headers. + +You can also set the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable to `true`, which clears the lists and enables `ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto`. + +For applications targeting .NET 9.0 or less, you can set the `Microsoft.AspNetCore.HttpOverrides.IgnoreUnknownProxiesWithoutFor` [AppContext](/dotnet/fundamentals/runtime-libraries/system-appcontext) switch to `"true"` or `1` to get back to the previous behavior. Alternatively, set the `MICROSOFT_ASPNETCORE_HTTPOVERRIDES_IGNORE_UNKNOWN_PROXIES_WITHOUT_FOR` environment variable. + +> [!NOTE] +> In cloud environments, the proxy IP(s) can change over the lifetime of the app and `ASPNETCORE_FORWARDEDHEADERS_ENABLED` is sometimes used to make forwarded headers work. + +## Affected APIs + +- +- +- +- + +## See also + +- [Configure ASP.NET Core to work with proxy servers and load balancers](/aspnet/core/host-and-deploy/proxy-load-balancer) From e8b99090e35af6849383fcfc019e761aed1b93bd Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Fri, 15 Aug 2025 18:23:15 -0700 Subject: [PATCH 3/4] human edits --- docs/core/compatibility/9.0.md | 15 +++++----- .../8.0/forwarded-headers-unknown-proxies.md | 29 ++++++++++--------- docs/core/compatibility/toc.yml | 4 +++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/docs/core/compatibility/9.0.md b/docs/core/compatibility/9.0.md index 4173ed2b3f948..aee1b828ef5af 100644 --- a/docs/core/compatibility/9.0.md +++ b/docs/core/compatibility/9.0.md @@ -13,13 +13,14 @@ If you're migrating an app to .NET 9, the breaking changes listed here might aff ## ASP.NET Core -| Title | Type of change | Introduced version | -|----------------------------------------------------------------------------------------------------------------------------|---------------------|--------------------| -| [DefaultKeyResolution.ShouldGenerateNewKey has altered meaning](aspnet-core/9.0/key-resolution.md) | Behavioral change | Preview 3 | -| [Dev cert export no longer creates folder](aspnet-core/9.0/certificate-export.md) | Behavioral change | RC 1 | -| [HostBuilder enables ValidateOnBuild/ValidateScopes in development environment](aspnet-core/9.0/hostbuilder-validation.md) | Behavioral change | Preview 7 | -| [Legacy Mono and Emscripten APIs not exported to global namespace](aspnet-core/9.0/legacy-apis.md) | Source incompatible | GA | -| [Middleware types with multiple constructors](aspnet-core/9.0/middleware-constructors.md) | Behavioral change | RC 1 | +| Title | Type of change | +|------------------------------------------------------------------------------------------------|-------------------| +| [DefaultKeyResolution.ShouldGenerateNewKey altered meaning](aspnet-core/9.0/key-resolution.md) | Behavioral change | +| [Dev cert export no longer creates folder](aspnet-core/9.0/certificate-export.md) | Behavioral change | +| [Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies](aspnet-core/8.0/forwarded-headers-unknown-proxies.md) | Behavioral change | +| [HostBuilder enables ValidateOnBuild/ValidateScopes in development environment](aspnet-core/9.0/hostbuilder-validation.md) | Behavioral change | +| [Legacy Mono and Emscripten APIs not exported to global namespace](aspnet-core/9.0/legacy-apis.md) | Source incompatible | +| [Middleware types with multiple constructors](aspnet-core/9.0/middleware-constructors.md) | Behavioral change | ## Containers diff --git a/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md b/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md index ef0f96d166ace..a79fabce1b706 100644 --- a/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md +++ b/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md @@ -1,29 +1,33 @@ --- title: "Breaking change: Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies" -description: Learn about the breaking change in ASP.NET Core 8.0.17 where Forwarded Headers Middleware now ignores headers from proxies that are not explicitly configured as trusted. -ms.date: 01/16/2025 +description: Learn about the breaking change in ASP.NET Core where Forwarded Headers Middleware now ignores headers from proxies that aren't explicitly configured as trusted. +ms.date: 08/15/2025 --- # Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies -Starting in ASP.NET Core 8.0.17 and 9.0.6, the Forwarded Headers Middleware ignores all `X-Forwarded-*` headers from proxies that are not explicitly configured as trusted. This change was made for security hardening, as the proxy and IP lists weren't being applied in all cases. +Starting in ASP.NET Core 8.0.17 and 9.0.6, the Forwarded Headers Middleware ignores all `X-Forwarded-*` headers from proxies that aren't explicitly configured as trusted. This change was made for security hardening, as the proxy and IP lists weren't being applied in all cases. ## Version introduced ASP.NET Core 8.0.17 +ASP.NET Core 9.0.6 ## Previous behavior -Previously, the middleware, when not configured to use `X-Forwarded-For`, would process `X-Forwarded-Prefix`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers from any source, potentially allowing malicious or misconfigured proxies/clients to spoof these headers and affect your application's understanding of client information. +Previously, the middleware, when not configured to use `X-Forwarded-For`, processed `X-Forwarded-Prefix`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers from any source. That behavior potentially allowed malicious or misconfigured proxies/clients to spoof these headers and affect an application's understanding of client information. ## New behavior -With this change, only headers sent by known, trusted proxies (as configured via and ) are processed. Headers from unknown sources are ignored. +Starting in .NET 8 and .NET 9 servicing releases, only headers sent by known, trusted proxies (as configured via and ) are processed. Headers from unknown sources are ignored. -This can cause behavior like infinite redirects if you're using the HTTPS redirection middleware and using TLS termination in your proxy. Or authentication to fail if using TLS termination and expecting an HTTPS request. +> [!NOTE] +> If your deployment relied on forwarded headers from proxies not configured in your application's trusted proxy list, those headers are no longer honored. + +This change can cause behavior like infinite redirects if you're using the HTTPS redirection middleware and using TLS termination in your proxy. It can also cause authentication to fail if you're using TLS termination and expecting an HTTPS request. ## Type of breaking change -This change affects [behavioral change](../../categories.md#behavioral-change). +This change is a [behavioral change](../../categories.md#behavioral-change). ## Reason for change @@ -31,7 +35,7 @@ The change was made for security hardening, as the proxy and IP lists weren't be ## Recommended action -**Review your deployment topology:** Ensure that all legitimate proxy servers in front of your app are properly added to `KnownProxies` or `KnownNetworks` in your configuration. +Review your deployment topology. Ensure that all legitimate proxy servers in front of your app are properly added to `KnownProxies` or `KnownNetworks` in your configuration. ```csharp app.UseForwardedHeaders(new ForwardedHeadersOptions @@ -49,21 +53,18 @@ app.UseForwardedHeaders(new ForwardedHeadersOptions }); ``` -**If you wish to enable previous behavior:** You may need to relax your configuration, but this is **not recommended** due to security risks. You can do this by clearing the `KnownNetworks` and `KnownProxies` lists in to allow any proxy or network to forward these headers. +If you wish to enable the previous behavior, which isn't recommended due to security risks, you can do so by clearing the `KnownNetworks` and `KnownProxies` lists in to allow any proxy or network to forward these headers. You can also set the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable to `true`, which clears the lists and enables `ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto`. -For applications targeting .NET 9.0 or less, you can set the `Microsoft.AspNetCore.HttpOverrides.IgnoreUnknownProxiesWithoutFor` [AppContext](/dotnet/fundamentals/runtime-libraries/system-appcontext) switch to `"true"` or `1` to get back to the previous behavior. Alternatively, set the `MICROSOFT_ASPNETCORE_HTTPOVERRIDES_IGNORE_UNKNOWN_PROXIES_WITHOUT_FOR` environment variable. +For applications that target .NET 9 or earlier, you can set the `Microsoft.AspNetCore.HttpOverrides.IgnoreUnknownProxiesWithoutFor` [AppContext](/dotnet/fundamentals/runtime-libraries/system-appcontext) switch to `"true"` or `1` to get back to the previous behavior. Alternatively, set the `MICROSOFT_ASPNETCORE_HTTPOVERRIDES_IGNORE_UNKNOWN_PROXIES_WITHOUT_FOR` environment variable. > [!NOTE] -> In cloud environments, the proxy IP(s) can change over the lifetime of the app and `ASPNETCORE_FORWARDEDHEADERS_ENABLED` is sometimes used to make forwarded headers work. +> In cloud environments, the proxy IPs can change over the lifetime of the app, and `ASPNETCORE_FORWARDEDHEADERS_ENABLED` is sometimes used to make forwarded headers work. ## Affected APIs - -- -- -- ## See also diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 724e1f2485cca..084f4a27ecab9 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -160,6 +160,8 @@ items: href: aspnet-core/9.0/key-resolution.md - name: Dev cert export no longer creates folder href: aspnet-core/9.0/certificate-export.md + - name: Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies + href: aspnet-core/8.0/forwarded-headers-unknown-proxies.md - name: HostBuilder enables ValidateOnBuild/ValidateScopes in development environment href: aspnet-core/9.0/hostbuilder-validation.md - name: Legacy Mono and Emscripten APIs not exported to global namespace @@ -316,6 +318,8 @@ items: href: aspnet-core/8.0/concurrencylimitermiddleware-obsolete.md - name: Custom converters for serialization removed href: aspnet-core/8.0/problemdetails-custom-converters.md + - name: Forwarded Headers Middleware ignores X-Forwarded-* headers from unknown proxies + href: aspnet-core/8.0/forwarded-headers-unknown-proxies.md - name: ISystemClock is obsolete href: aspnet-core/8.0/isystemclock-obsolete.md - name: "Minimal APIs: IFormFile parameters require anti-forgery checks" From f8c20bafd63d33da9b57230572e75e846973c113 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Fri, 15 Aug 2025 18:37:23 -0700 Subject: [PATCH 4/4] fix xrefs --- .../aspnet-core/8.0/forwarded-headers-unknown-proxies.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md b/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md index a79fabce1b706..62fcc4db7e592 100644 --- a/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md +++ b/docs/core/compatibility/aspnet-core/8.0/forwarded-headers-unknown-proxies.md @@ -18,7 +18,7 @@ Previously, the middleware, when not configured to use `X-Forwarded-For`, proces ## New behavior -Starting in .NET 8 and .NET 9 servicing releases, only headers sent by known, trusted proxies (as configured via and ) are processed. Headers from unknown sources are ignored. +Starting in .NET 8 and .NET 9 servicing releases, only headers sent by known, trusted proxies (as configured via and ) are processed. Headers from unknown sources are ignored. > [!NOTE] > If your deployment relied on forwarded headers from proxies not configured in your application's trusted proxy list, those headers are no longer honored. @@ -35,7 +35,7 @@ The change was made for security hardening, as the proxy and IP lists weren't be ## Recommended action -Review your deployment topology. Ensure that all legitimate proxy servers in front of your app are properly added to `KnownProxies` or `KnownNetworks` in your configuration. +Review your deployment topology. Ensure that all legitimate proxy servers in front of your app are properly added to or in your configuration. ```csharp app.UseForwardedHeaders(new ForwardedHeadersOptions @@ -53,7 +53,7 @@ app.UseForwardedHeaders(new ForwardedHeadersOptions }); ``` -If you wish to enable the previous behavior, which isn't recommended due to security risks, you can do so by clearing the `KnownNetworks` and `KnownProxies` lists in to allow any proxy or network to forward these headers. +If you wish to enable the previous behavior, which isn't recommended due to security risks, you can do so by clearing the `KnownNetworks` and `KnownProxies` lists in to allow any proxy or network to forward these headers. You can also set the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable to `true`, which clears the lists and enables `ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto`.