Allow known safe values for X-Forwarded-Proto without requiring KnownProxies / KnownIPNetworks configuration
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Is your feature request related to a problem? Please describe the problem.
.NET 10 removed the AppContext switch `IgnoreUnknownProxiesWithoutFor`, requiring configuration of `ForwardedHeadersOptions.KnownProxies` / `.KnownIPNetworks` to recognize `X-Forwarded-Proto` in `ForwardedHeadersMiddleware`. While the reason for this change is great, it seems overkill to protect from malicious protocol injection (e.g. https://github.com/greenpau/caddy-security/issues/270).
### Describe the solution you'd like
Wouldn't it suffice to check if the forwarded protocol is `http` or `https` (case-insensitively), and allowing it if it is, despite the proxy not being known? This would greatly simplify cases where `ForwardedHeadersOptions.ForwardedHeaders` only allows `ForwardedHeaders.XForwardedProto`, without (per my understanding) introducing any security risks originally mitigated by this change.
### Additional context
I've implemented this behavior as a workaround in middleware like so (the call site of this function rejects requests if the function returns false):
```csharp
// Mitigate malicious X-Forwarded-Proto values (https://github.com/greenpau/caddy-security/issues/270)
if (!rq.Scheme.EqualsIgnoreCase("http") && !rq.Scheme.EqualsIgnoreCase("https"))
{
logger.LogWarning("Received request with invalid scheme: '{scheme}', please check your reverse proxy configuration",
rq.Scheme);
return false;
}
```
This is accompanied by the following code in `Startup.cs`:
```csharp
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
// The X-Forwarded-Proto value gets validated in RequestVerificationMiddleware so we can trust any proxy
ForwardedHeaders = ForwardedHeaders.XForwardedProto,
KnownIPNetworks = { new IPNetwork(IPAddress.Any, 0), new IPNetwork(IPAddress.IPv6Any, 0) }
});
````
Contributor guide
Assessment
This issue has not been assessed yet.