diff --git a/eng/PatchConfig.props b/eng/PatchConfig.props index 42d6a03817db..a84077104272 100644 --- a/eng/PatchConfig.props +++ b/eng/PatchConfig.props @@ -39,6 +39,7 @@ Later on, this will be checked using this condition: + Microsoft.AspNetCore.HttpOverrides; diff --git a/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs b/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs index 88317c455109..be254a879e3d 100644 --- a/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs +++ b/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs @@ -24,6 +24,7 @@ public class ForwardedHeadersMiddleware private readonly ForwardedHeadersOptions _options; private readonly RequestDelegate _next; private readonly ILogger _logger; + private readonly bool _ignoreUnknownProxiesWithoutFor; private bool _allowAllHosts; private IList _allowedHosts; @@ -90,6 +91,18 @@ public ForwardedHeadersMiddleware(RequestDelegate next, ILoggerFactory loggerFac _logger = loggerFactory.CreateLogger(); _next = next; + if (AppContext.TryGetSwitch("Microsoft.AspNetCore.HttpOverrides.IgnoreUnknownProxiesWithoutFor", out var enabled) + && enabled) + { + _ignoreUnknownProxiesWithoutFor = true; + } + + if (Environment.GetEnvironmentVariable("MICROSOFT_ASPNETCORE_HTTPOVERRIDES_IGNORE_UNKNOWN_PROXIES_WITHOUT_FOR") is string env + && (env.Equals("true", StringComparison.OrdinalIgnoreCase) || env.Equals("1"))) + { + _ignoreUnknownProxiesWithoutFor = true; + } + PreProcessHosts(); } @@ -228,12 +241,17 @@ public void ApplyForwarders(HttpContext context) { var set = sets[entriesConsumed]; - // For the first instance, allow remoteIp to be null for servers that don't support it natively. - if (currentValues.RemoteIpAndPort != null && checkKnownIps && !CheckKnownAddress(currentValues.RemoteIpAndPort.Address)) + // Opt-out of breaking change behavior where we now always check KnownProxies and KnownNetworks + // It used to be guarded by the ForwardedHeaders.XForwardedFor flag, but now we always check it. + if (!_ignoreUnknownProxiesWithoutFor || checkFor) { - // Stop at the first unknown remote IP, but still apply changes processed so far. - _logger.LogDebug(1, $"Unknown proxy: {currentValues.RemoteIpAndPort}"); - break; + // For the first instance, allow remoteIp to be null for servers that don't support it natively. + if (currentValues.RemoteIpAndPort != null && checkKnownIps && !CheckKnownAddress(currentValues.RemoteIpAndPort.Address)) + { + // Stop at the first unknown remote IP, but still apply changes processed so far. + _logger.LogWarning(1, $"Unknown proxy: {currentValues.RemoteIpAndPort}"); + break; + } } if (checkFor)