IIS Hardening - Handler Mappings, Modules and ISAPI Filters

22 March 2015

On my server I'm running various different types of sites. Static files only, older Web-forms applications and some ASP.NET MVC sites.

I don't use cookie-less sessions, any WCF services, no CGI or COM objects. I also don't use ASP.NET membership services.

So all my application pools are running CLR v4.0 in 64Bit in integrated mode or 'No Managed Code' at all.

Considering this, I can get rid of several built-in modules.

This is to reduce the attack surface but also possibly improve performance.

Before applying any of these changes, make sure you've read IIS Hardening - File Extensions

IIS Components

First, lets review the installed components:

Get-WindowsOptionalFeature -Online | Where {$_.FeatureName -match "^IIS-" -and $_.State -eq "Enabled"} | Sort FeatureName | Select FeatureName

this shows all the components like this:

 FeatureName
 -----------
 IIS-ApplicationDevelopment
 IIS-ApplicationInit
 IIS-ASPNET45
 IIS-BasicAuthentication
 IIS-CGI
 IIS-CommonHttpFeatures
 IIS-DefaultDocument
 IIS-HealthAndDiagnostics
 IIS-HttpCompressionDynamic
 IIS-HttpCompressionStatic
 IIS-HttpErrors
 ...

Review them all and decide whether you need them. In my case I had a few left-overs from old sites, I removed them:

& Disable-WindowsOptionalFeature -Online -FeatureName IIS-CGI
& Disable-WindowsOptionalFeature -Online -FeatureName IIS-IISCertificateMappingAuthentication
& Disable-WindowsOptionalFeature -Online -FeatureName IIS-BasicAuthentication

Handler Mappings on the machine level

I'm not using 32bit AppPools, so I can remove all 32bit mappings

 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='xamlx-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='rules-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='xoml-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='svc-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='AXD-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='PageHandlerFactory-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='SimpleHandlerFactory-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='WebServiceHandlerFactory-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='aspq-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='cshtm-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='cshtml-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='vbhtm-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='vbhtml-ISAPI-4.0_32bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='ExtensionlessUrlHandler-ISAPI-4.0_32bit'}

I'm not using Classic mode, so I can remove all related IASPI mappings:

 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='xamlx-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='rules-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='xoml-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='svc-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='AXD-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='PageHandlerFactory-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='SimpleHandlerFactory-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='WebServiceHandlerFactory-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='aspq-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='cshtm-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='cshtml-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='vbhtm-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='vbhtml-ISAPI-4.0_64bit'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='ExtensionlessUrlHandler-ISAPI-4.0_64bit'}

I'm not using WFC service or any sort of remoting:

 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='xamlx-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='rules-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='xoml-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='svc-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='HttpRemotingHandlerFactory-rem-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='HttpRemotingHandlerFactory-soap-Integrated-4.0'}

I don't need protection for .*html files

 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='cshtm-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='cshtml-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='vbhtm-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='vbhtml-Integrated-4.0'}

Other handlers I don't need

 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='WebAdminHandler-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='SimpleHandlerFactory-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='aspq-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='ISAPI-dll'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='ScriptHandlerFactoryAppServices-Integrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='ScriptResourceIntegrated-4.0'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='TRACEVerbHandler'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='OPTIONSVerbHandler'}
 Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/handlers" -name "." -AtElement @{name='TraceHandler-Integrated-4.0'}

WebAdminHandler handles WebAdmin.axd to display the ASP.NET Website Administration Toolkit, you can remove this if you don't use that builtin feature.

SimpleHandlerFactory handles *.asmx and *_AppService.axd to support Web service calls via Ajax.

aspq - I have no idea what this is. I never used, I don't need it.

ScriptHandlerFactoryAppServices handles *_AppService.axd for an Application Service within ASP.NET.

ScriptResourceIntegrated handles ScriptResource.axd which I don't use.

TRACEVerbHandler and OPTIONSVerbHandler handle trace and options http requests, I don't support them.

TraceHandler handles trace.axd which you don't want on a production server.

ISAPI-dll for old school ISAPI extensions, don't want them.

Handler Mappings I want to keep

After removing all those mappings I'm left with these:

<handlers accessPolicy="Read, Script">
   <add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" preCondition="integratedMode,runtimeVersionv4.0" />
   <add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" preCondition="integratedMode,runtimeVersionv4.0" />
   <add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
   <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
   <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule" resourceType="Either" requireAccess="Read" />
</handlers>

These are enough to run all my sites, that's 5 out of 87 handler mappings.

Do we really need those ISAPI thingies?

Even though some people, say you need the ISAPI ASP.NET filter and Restrictions, I found that I don't, so lets disable them:

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/isapiFilters/filter[@name='ASP.Net_4.0_32bit']" -name "enabled" -value "False"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/isapiFilters/filter[@name='ASP.Net_4.0_64bit']" -name "enabled" -value "False"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/security/isapiCgiRestriction/add[@path='%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll']" -name "allowed" -value "False"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/security/isapiCgiRestriction/add[@path='%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll']" -name "allowed" -value "False"

You can also get rid of them completely:

Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/isapiFilters" -name "." -AtElement @{name='ASP.Net_4.0_32bit'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/isapiFilters" -name "." -AtElement @{name='ASP.Net_4.0_64bit'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/security/isapiCgiRestriction" -name "." -AtElement @{path='%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/security/isapiCgiRestriction" -name "." -AtElement @{path='%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll'}

Http Modules on the machine level:

Again depending on your sites and technology there are a bunch of modules you don't need. I don't use most of the ASP.NET features, so in my case I could remove the following:

Managed Modules

Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='WindowsAuthentication'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='FormsAuthentication'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='RoleManager'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='UrlAuthorization'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='FileAuthorization'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='AnonymousIdentification'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='Profile'}
Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='UrlMappingsModule'}

Native Modules

Remove-WebConfigurationProperty  -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/modules" -name "." -AtElement @{name='IsapiModule'}


Pages in this section

Categories

ASP.Net | Community | Development | IIS | IT Pro | Security | SQL (Server) | Tools | Web | Work on the road | Windows