On my site, I want to disallow HTTP HEAD
requests and have them answered with the 405 status code (Method not allowed
). To achieve this I have the following in my web.config
file:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="TelemetryCorrelationHttpModule" />
<add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="integratedMode,managedHandler" />
<remove name="ApplicationInsightsWebTracking" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
</modules>
<handlers>
<clear />
<add name="DenyHead" path="*" verb="HEAD" type="System.Web.HttpMethodNotAllowedHandler" />
<add name="DebugAttachHandler" path="DebugAttach.aspx" verb="DEBUG" type="System.Web.HttpDebugHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="Read" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<security>
<requestFiltering allowDoubleEscaping="true">
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="HEAD" allowed="true" />
<add verb="DEBUG" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
Unfortunately, this doesn't work - I'm receiving bog-standard 404s instead.
Enabling failed request tracing yields the following:
20 HANDLER_CHANGED OldHandlerName
NewHandlerName DenyHead
NewHandlerType System.Web.HttpMethodNotAllowedHandler
...
61 AspNetPipelineEnter Data1 <Application_BeginRequest in my ASP.NET application>
...
135 HANDLER_CHANGED OldHandlerName System.Web.HttpMethodNotAllowedHandler
NewHandlerName System.Web.Mvc.MvcHandler
...
169 MODULE_SET_RESPONSE_ERROR_STATUS Notification EXECUTE_REQUEST_HANDLER
HttpStatus 404
This seems to show that the DenyHead
handler is somehow being replaced/overridden by my MVC application, but there's no code in my app that does anything of the sort.
I've tried alternative recommendations such as the answers here, but they give the same result.
- Request filtering isn't an option because the status code it returns is not configurable (it always returns a 404).
- Action filters aren't an option because they won't be hit for static content, and I don't want to send everything through the MVC pipeline.