HttpAddUrl on localhost fails for non-admin users

2020-07-24 04:42发布

Using the Windows HTTP API I'm running a HTTP file server on localhost.

This involves calling HttpAddUrl(hRequestQueue, L"http://localhost:80/", NULL).

This fails with ERROR_ACCESS_DENIED unless the user runs the application as administrator. I need this functionality for users who don't have admin privileges. (What's wrong with a user running a localhost server anyway? It's just for the user themselves.)

I found a hotfix for Vista and XP which seems aimed at solving this, but there's nothing for Windows 7. The article implies it was fixed in Vista SP1, and I have Windows 7 SP1 and it's still a problem - did the fix not make it to Windows 7?

Is there anything else I can do to get the server to run for non-admins?

3条回答
太酷不给撩
2楼-- · 2020-07-24 05:23

Ports 1-1024, by default, require administrative access. Otherwise you get error code 5 (ACCESS_DENIED). If you attempt to bind to a port above 1024, e.g.:

http://localhost:8080/

it will work for non-admin users. In your case you tried to listen on port 80, which HttpServer API limits to administrators.

Everything in Windows is controlled by Access Control Lists (ACLs); this includes the listen ports allowed when using HttpServer. You can display the current ACLs used by http by running:

>netsh http show urlacl

If you do that, you'll see a lot of ACLs already defined by various systems.

Windows Communication Foundation

One ACL entry is particularly interesting:

Reserved URL            : http://+:80/Temporary_Listen_Addresses/
   User: \Everyone
      Listen: Yes
      Delegate: No
      SDDL: D:(A;;GX;;;WD)

Everyone is granted the right to listen on port 80, as long as you live off of:

/Temporary_Listen_Addresses/

This url is used by Windows Communication Foundation (WCF), which normally constructs a URL of the form:

http://+:80/Temporary_Listen_Addresses/{random-guid}/

It also means, if you really want port 80, you can listen with your own, for example:

http://localhost:80/Temporary_Listen_Addresses/64E3DCC6-FE47-4A86-87F4-48D2E1B44AE9/ 

As long as nobody is already using port 80 (i'm looking at your Skype!), you'll get it.

WinSock listening sockets do not require admin

While the HttpServer API has ACLs controlling access to ports below 1024, it should be noted that the WinSock API has no restriction.

If you want to use WinSock to open a listening socket on port 80, you do not need to be an administrator. It is only the Http api that has the ACL.

查看更多
淡お忘
3楼-- · 2020-07-24 05:24

Answering my own question, but found a workaround: the IANA port numbers state ports 49152-65535 are for dynamic/private purposes. HttpAddUrl for localhost on a port >= 49152 works fine for non-admins.

查看更多
走好不送
4楼-- · 2020-07-24 05:32

This must be configured on system level because HTTP API uses http.sys (kernel driver). You can use netsh.exe command executed with Administrator privileges to grant access to the user or application:

netsh http add urlacl url=http://localhost:80/ user=EVERYONE listen=yes delegate=no
查看更多
登录 后发表回答