8

I'm looking to remove the TRACE method from my web site in IIS 8.5 (Windows Server 2012 R2 Datacenter). I have implemented this using request filtering as below:

<system.webServer>
  <security>
    <requestFiltering>
      <verbs allowUnlisted="true">
        <add verb="TRACE" allowed="false" />
      </verbs>
    </requestFiltering>
  </security>
</system.webServer>

This prevents TRACE requests, but if I send an OPTIONS request, it still lists out TRACE in the Allow and Public headers. I've reset IIS, but can't get TRACE out of OPTIONS. I don't want to deny OPTIONS.

This is problematic because it appears that a compliance scan we abide by uses OPTIONS as its indicator that TRACE is enabled. I know this is not correct, but that's the criteria I have to meet.

Is there any way of getting OPTIONS to report the available methods correctly?

alergy
  • 183
  • 1
  • 1
  • 6

1 Answers1

7

Interesting question. All the methods to remove response headers from IIS don't seem to work for the Allow and Public headers, an OPTIONS request always returns:

Allow:  OPTIONS, TRACE, GET, HEAD, POST
Public: OPTIONS, TRACE, GET, HEAD, POST

regardless what the server actually allows.

All requests in IIS are handled by modules, the OPTIONS requests are handled by the ProtocolSupportModule which is not essential and as it seems pretty dumb.

If we remove that module, the server doesn't response to Options request anymore, which you still want to support, so we have to use another module to answer those.

Open:

%SystemRoot%\System32\inetsrv\config\applicationHost.config

and search for OPTIONSVerbHandler comment that line and while you are at it the one above (TRACEVerbHandler) as well. Now add a new node:

<add name="MyOPTIONSVerbHandler" path="*" verb="OPTIONS" modules="StaticFileModule" requireAccess="None" />

the whole block should look like this:

    <!--  <add name="TRACEVerbHandler" path="*" verb="TRACE" modules="ProtocolSupportModule" requireAccess="None" /> 
          <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" /> -->
          <add name="MyOPTIONSVerbHandler" path="*" verb="OPTIONS" modules="StaticFileModule" requireAccess="None" /> 

Now the staticFileModule will process the OPTIONS requests but it will not return any content.

If you now make a OPTIONS request to the server, you wont get a Allow nor a Public header, you can add them easily in web.config

<system.webServer>
 <httpProtocol>
      <customHeaders>
          <add name="Allow"  value="GET,POST,HEAD" />  
          <add name="Public" value="GET,POST,HEAD" />
      </customHeaders>
  </httpProtocol>        
</system.webServer>

now your OPTIONS requests work as required, but those extra headers are also sent with any GET or POST requests which I think is still valid http.

If you only want to use those headers for OPTIONS requests you could write a simple http module that sets these headers and use it instead of the StaticFileModule I used above.

Peter Hahndorf
  • 13,763
  • 3
  • 37
  • 58
  • thanks for the answer, I had wondered if the OPTIONS handler needed replacing, your answer gives me a route to handle this. – alergy Jun 03 '15 at 08:58