httpiisweb-configtracehttp-verbs

IIS: How to disable HTTP method TRACE?


I followed this, which led to this to try to disable my website from accepting the TRACE method (verb). Basically I added the section below to <system.webServer> inside Web.config (Default Web Site and the other website):

<security>
   <requestFiltering>
       <verbs applyToWebDAV="false">
          <add verb="TRACE" allowed="false" />
       </verbs>
   </requestFiltering>
</security>

It didn´t work. Then I went to C:\Windows\System32\inetsrv\config\applicationHost.config and replaced all handlers' verb inside <handlers>. In a nutshell, all lines like this:

<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />

Became this:

<add name="StaticFile" path="*" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />

I even restarted the server but when I check the available methods, TRACE is still there:

$ curl -I -X OPTIONS https://example.com/mysite
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Public: OPTIONS, TRACE, GET, HEAD, POST
X-XSS-Protection: 1; mode=block
Date: Thu, 07 Feb 2019 21:03:49 GMT
Content-Length: 0

So, how do I get rid of it?


Solution

  • To truly block TRACE requests, you should still keep a request filtering rule with TRACE verb blocked.

    The curl command sends an OPTIONS request to IIS, and the ProtocolSupportModule generates the response message,

    https://learn.microsoft.com/en-us/iis/get-started/introduction-to-iis/iis-modules-overview

    However, Microsoft did not design any settings in system.webServer/httpProtocol section for you to change the value of the headers so as to hide TRACE from there.

    But a workaround is to use URL Rewrite module,

    https://blogs.msdn.microsoft.com/benjaminperkins/2012/11/02/change-or-modify-a-response-header-value-using-url-rewrite/

    where you create two outbound rules for Allow and Public headers,

    <rewrite>
        <outboundRules>
            <rule name="ChangeHeaders" stopProcessing="false">
                <match serverVariable="RESPONSE_Allow" pattern="OPTIONS, TRACE, GET, HEAD, POST" />
                <action type="Rewrite" value="OPTIONS, GET, HEAD, POST" />
            </rule>
            <rule name="Public">
                <match serverVariable="RESPONSE_Public" pattern="OPTIONS, TRACE, GET, HEAD, POST" />
                <action type="Rewrite" value="OPTIONS, GET, HEAD, POST" />
            </rule>
        </outboundRules>
    </rewrite>