Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsafe pattern for port restriction in documentation #29399

Closed
hacst opened this issue Jun 1, 2023 · 3 comments · Fixed by #29463
Closed

Unsafe pattern for port restriction in documentation #29399

hacst opened this issue Jun 1, 2023 · 3 comments · Fixed by #29463
Assignees
Labels
doc-bug seQUESTered Identifies that an issue has been imported into Quest. Source - Docs.ms Docs Customer feedback via GitHub Issue

Comments

@hacst
Copy link

hacst commented Jun 1, 2023

Imo the recommendations given for port restriction in https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-7.0#require-host are unsafe. They rely solely on the Host header transmitted by the client. This header often is fully client controlled. E.g. if a host has an exposed port 80 and an internal management port 5001 which is not exposed to the internet with endpoints restricted by using .RequireHost("*:5001"), this can be trivially circumvented by doing something like curl --header "Host: whatever:5001" http://thepublicserver/healthz which connects on port 80 but stating port 5001 in the host header passing the RequireHost condition.

The linked https://learn.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-7.0#host-matching-in-routes-with-requirehost and the extension method documentation in https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.routingendpointconventionbuilderextensions.requirehost?view=aspnetcore-7.0 also do not make it clear that this relies on the potentially user controlled Host header field.

I think I've seen this implementation pattern recommended in other locations in the documentation and samples where the goal is to restrict endpoints to a given port. At the very least there should be a warning, that this is generally not a safe way to achieve such a restriction. Ideally a safe pattern would be suggested. Even better would be having some built-in way to achieve this common requirement in a safe way and documenting that. E.g. some RequireLocalPort, RequireLocalHost etc. that actually checks the local port / local IP in the http context instead of the host header. It seems this was suggested in dotnet/aspnetcore#46057 which is now closed & locked, though I am not sure the security angle was given sufficient appreciation there.


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.


Associated WorkItem - 98270

@guardrex
Copy link
Collaborator

guardrex commented Jun 1, 2023

I have one Blazor example that filters requests for middleware that relies on HttpContext.Request.Host.Port. The example works well with HttpContext.Request.HttpContext.Connection.LocalPort, too. However, it also uses HttpContext.Request.Host to match the host. I'm considering a NOTE for that example to raise awareness on this.

For ...

the extension method documentation in https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.routingendpointconventionbuilderextensions.requirehost?view=aspnetcore-7.0

... we don't control that here. That documentation is driven directly by the API itself, so you'd need to open an issue for the product unit asking them about making a change to the API remarks that generate the docs. I think you should do that and re-raise the whole subject with them ...

https://github.com/dotnet/aspnetcore/issues

Besides anything they might do with API remarks, I think the more important point is that dotnet/aspnetcore#46057 closed automatically just as it was about to reach critical mass 💣 and turn into a work item. If you open a new issue asking them to consider proceeding with new API, would you mind tagging me in your opening comment? I'd like to follow the discussion.

Please add ...

cc: @guardrex https://github.com/dotnet/AspNetCore.Docs/issues/29399

Rick, we might be able to craft a one/two-line NOTE for the repo-wide INCLUDES that can appear anywhere. I'm going to wait and see how this plays out before I do anything for that Blazor doc. 👂

@guardrex
Copy link
Collaborator

guardrex commented Jun 1, 2023

Language ideas for discussion ...

API that relies on the Host header, such as RequireHost or HttpRequest.Host, is subject to potential spoofing by clients.

In high security scenarios, consider assigning a value to HttpRequest.Host in middleware before UseRouting is called and using HttpContext.Connection in places where either or both the IP address and port are checked. A host (domain name) can only be checked via a reverse DNS lookup using a registered IP address.

...

> [!WARNING]
> API that relies on the [Host header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Host), such as <xref:Microsoft.AspNetCore.Builder.RoutingEndpointConventionBuilderExtensions.RequireHost%2A> or <xref:Microsoft.AspNetCore.Http.HttpRequest.Host%2A?displayProperty=nameWithType>, is subject to potential spoofing by clients.
>
> In high security scenarios, consider assigning a value to <xref:Microsoft.AspNetCore.Http.HttpRequest.Host?displayProperty=nameWithType> in [middleware](xref:fundamentals/middleware/write) before <xref:Microsoft.AspNetCore.Builder.EndpointRoutingApplicationBuilderExtensions.UseRouting%2A> is called and using <xref:Microsoft.AspNetCore.Http.HttpContext.Connection%2A?displayProperty=nameWithType> in places where either or both the IP address and port are checked. A host (domain name) can only be checked via a reverse DNS lookup using a registered IP address.

BUT ... if this subject is important enough to add a section to the main repo's Routing article, then the NOTE INCLUDE would just have a one-liner with a cross-link to the new section.

@Rick-Anderson
Copy link
Contributor

Rick-Anderson commented Jun 8, 2023

... we don't control that here. That documentation is driven directly by the API itself, so you'd need to open an issue for the product unit asking them about making a change to the API remarks that generate the docs. I think you should do that and re-raise the whole subject with them ...

@david-acker I think an issue should be opened and a PR made to these API's so the API docs warn about host spoofing. That could be done after the PU (Product Unit) approves our warning language.

@github-actions github-actions bot added seQUESTered Identifies that an issue has been imported into Quest. and removed reQUEST Triggers an issue to be imported into Quest labels Jun 8, 2023
@Rick-Anderson Rick-Anderson moved this from Next to 👀 In review in dotnet/AspNetCore.Docs June 2023 Jun 8, 2023
@github-project-automation github-project-automation bot moved this from 👀 In review to ✅ Done in dotnet/AspNetCore.Docs June 2023 Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-bug seQUESTered Identifies that an issue has been imported into Quest. Source - Docs.ms Docs Customer feedback via GitHub Issue
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants