aspnet / HttpSysServer

[Archived] A web server for ASP.NET Core based on the Windows Http Server API. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
106 stars 39 forks source link

Access denied exception in UrlGroup.RegisterPrefix #492

Closed cadwal closed 5 years ago

cadwal commented 5 years ago

I have a very odd problem with UrlPrefixes in development. Sample attached, don't use IISExpress when testing. (This comes from a larger Api hosted as a WinService)

Consider this configuration:

options.UrlPrefixes.Add("http://localhost:19800/");
options.UrlPrefixes.Add("http://" + Environment.MachineName + ":19800/");

If I run this as a regular user (from VS or command line), the first prefix works fine (as expected I believe, a port above 10000 on localhost/127.0.0.1 is ok for any user (TLS needs more though)). The second prefix fails (with error from subject), also as expected since I as a regular user has no access to do that.

Fixing the use of the second prefix should be done using (as a local admin)

netsh http add urlacl url=http://+:19800/ user=\ (or Everyone or similar to be even more permissive)

What really happens when that is done is that the second prefix still fails with same error, but now the first prefix also fails with the same error ?!. Highly confusing and I don't understand why....

I do have selfhosted WCF services where usage of urlacl:s works as expected, but I can't easily find the code to see what is different there compared to HttpSysServer. I don't think there is anything strange in the UrlGroup code.

TestAppHttpSys.zip

Tratcher commented 5 years ago

Note the netsh reservation url must match exactly what you pass to UrlPrefixes. Also, + reserves all hosts, it doesn't stack like * does.

cadwal commented 5 years ago

Ah, that is exactly what the documentation says. But not until this morning did I realise that I had made incorrect assumptions based on the word "match" when there were wildcards in the vicinity. I had assumed that match meant match a registration against the wildcard reservations, but it meant match the registration against the list of reservations. The wildcards are only used in http.sys routing, nothing else (right?).

And realising that I could also find ConnectionOrientedTransportDefaults.HostNameComparisonMode where it becomes obvious that WCF with default settings uses a strong wildcard (+) registration no matter what actual hostname I request it to listen on.

Tratcher commented 5 years ago

Correct.

cadwal commented 5 years ago

Additional notes from some additional testing for someone that comes across this issue: A prefix with host 127.0.0.1 only listens on the loopback interface. A prefix with host localhost listens on all interfaces but host header spoofing is blocked in HTTP.SYS and only traffic from localhost to localhost is allowed, but that is a software only thing it seems.