Aspnetcore: SignalR websocket not working if IIS SERVER header is empty

Created on 25 Mar 2019  路  9Comments  路  Source: dotnet/aspnetcore

Describe the bug

SignalR attempt to use websocket is failing if the "SERVER" header from IIS is empty.

To Reproduce

Steps to reproduce the behavior:

  1. Create a rule on IIS that empty the SERVER header from the responses
  2. Try a sample that use SignalR
  3. Check the javascript log, websocket connection attempt is failing, fallback to SSE
  4. If the rule is disabled, the websocket connection is OK

Expected behavior

Websocket connection should work whatever the SERVER header contains.

Additional context

ASPNET.CORE 2.2.3
Windows Server 2016/IIS

area-signalr

All 9 comments

Could you provide the method that you are using to set the Server header to empty?

Could you provide a full repro that illustrates the problem? It's likely to be a browser issue in this case, so we won't be able to do much about it.

Hi Guys,
The server header is cleared by an IIS Rule like described here:
https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers

Regarding the workflow to reproduce the issue, I just created a basic ASPNET.CORE website with basic credentials authentication with an SQLite database, and configured CORS just fined.
I created a simple HUB in the server side (c# of course), and added the signalR lib through libman using Visual Studio 2019. Everything works fine if I disable the IIS rule, ie signalR use successfuly websockets.
If I turn on the rule (SERVER header is then empty for security purpose), whatever the browser (Safari, Chrome, Edge, IE, Firefox), websockets failed to connect, so signalR fallback to SSE.

I'm don't think you can reproduce the issue with local IIS Express because there is no such configuration. You have to deploy a website to an IIS Server.

In addition, I actually set the 'SERVER' header response with '-' instead of empty string to workaround the bug.

When the Server header is present it is supposed to contain one or more characters according to the spec. Having it blank creates an invalid HTTP response.

I'd argue removing the header isn't much of a security enhancement, fingerprinting servers is simple with or without the header, but if you believe it gives you value you could remove the header instead.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <!--- Other things, probably system.web sections --->
  <system.webServer>
    <security>
      <requestFiltering removeServerHeader="true" />
    </security>
    <!--- Other system.webServer sections --->
  </system.webServer>
</configuration>

Looks like IIS rules like this can mess with WebSocket connections. @shirhatti we may need to investigate this from the IIS side. I see https://github.com/aspnet/AspNetCoreModule/issues/163 filed which seems very related.

@blowdart, could you telle me where am I supposed to put this web.config file ?
On my Windows server 2016, I have a c:inetpub folder with default content inside.
My web site is located under c:wwwrootMySite
But I cannot find any file containing the rules I created through IIS Manager.
I agree that if the spec is to provide a non empty string for the SERVER header, I could remove it. Have to test it.
Thank you

You should probably add it in your application's web.config, in the system.webServer section, rather than globally, which may be where your IIS manager created ones ended up.

Indeed, it did the trick :-) Thank you
Don't know if it is up to me to close the issue or you do ?

Was this page helpful?
0 / 5 - 0 ratings