IIS Case Study: Why my ISAPI filters are not getting loaded?

Last week I was working on an interesting case related to ISAPI filters not getting loaded. The complete description of the problem went like this

“I have an ISAPI filter at the web sites level that intercept the requests and authenticates users (using a similar implementation of forms authentication) before serving the protected asp.net web page. This ISAPI filter also implements the single sign on feature for various web other web applications. When we use a custom identity for application pool the ISAPI filter is not invoked and the users were able to access the protected web pages with out any authentication. To work around this, we need to add the custom identity user for application pool to local administrators group.”

Reading through the problem description, these are the questions to be answered

  1. Why the ISAPI filter is not invoked when we use a custom identity for application pool?
  2. Why the application pool identity needs to be part of local admin group to invoke the ISAPI filter?
  3. Why the ISAPI filter is invoked when the application pool identity is NETWORK SERVICE even though it is not part of Administrators group?

I would like to describe the root cause of the problem by reproducing the same behavior rather than explaining the complete troubleshooting steps.

To start with, we need to download the metabase explorer from https://support.microsoft.com/kb/840671. By default when you launch metabase explorer, it loads the local machines IIS metabase configurations by default. We are interested in the required permissions for the “Filters” node and the default permission list is shown in the below in Figure 1.

Figure1

For this demo purpose, lets consider ASP.NET 2.0 ISAPI filter as an example as shown below in Figure 2.

Figure 2

Now let’s enable ETW (Enterprise Tracing for Windows) tracing and see what we get in the trace. Make sure the application pool identity is NETWORK SERVICE before you enable the tracing. We can enable ETW tracing as explained below.

1) Create a provider file by name providers.guid with following entry

{3a2a4e84-4c21-4981-ae10-3fda0d9b0f83} 0xFFFFFFFE 5 IIS: WWW Server

2) Open up the command prompt and enable ETW Tracing using the following command

“logman start iistrace_etl –pf providers.guid –ets” (without the quotes) and press Enter.

If the worker process is active and the ISAPI filters are loaded you will get the output in the command prompt indicating that providers were activated.

3) Browse any of the .ASPX web pages to reproduce the behavior.

Once you finish, type “logman stop iistrace_etl -ets” (without the quotes) to stop tracing Now generate the report using tracerpt utility or log parser sample scripts “tracerpt iis_trace.etl”

4) Once the trace report is generated you will see all the ISAPI filter events as shown below for each ISAPI Filter

+-------------------------------------------------------------------------------------+
|Event Count Event Name Event Type Guid |
+-------------------------------------------------------------------------------------+
| 3 IISFilter FILTER_PREPROC_HEADERS_END {00237f0d-73eb-4bcf-a232-126693595847}|
| 3 IISFilter FILTER_PREPROC_HEADERS_START {00237f0d-73eb-4bcf-a232-126693595847}|
| 3 IISFilter FILTER_URL_MAP_END {00237f0d-73eb-4bcf-a232-126693595847}|
| 6 IISFilter FILTER_START {00237f0d-73eb-4bcf-a232-126693595847}|
| 6 IISFilter FILTER_END {00237f0d-73eb-4bcf-a232-126693595847}|
| 3 IISFilter FILTER_URL_MAP_START {00237f0d-73eb-4bcf-a232-126693595847}|
| 3 IISFilter FILTER_SET_REQ_HEADER {00237f0d-73eb-4bcf-a232-126693595847}|

Now let’s talk about the changes to break this.

Firstly, we will modify the default permissions set from “Filters” node as shown below. Remove IIS_WPG group from default permission list. See that we no more have the IIS_WPG group under the permissions in Figure 3.

Figure 3

Create a new user and configure that user as the custom identity for the application pool. Make sure to add the new user under IIS_WPG group.

We are ready for the next ETW tracing. Follow the same steps mentioned in the previous section to generate the ETW tracing and report. If you examine the differences in the new ETW trace, you will see that none of the ISAPI filter events are logged.

Now let’s try to answer the questions that we asked at the beginning

  • Why the ISAPI filter is not invoked when we use a custom identity for application pool?

As you can see the custom identity is part of IIS_WPG group and this group does not belongs to the permission set for “Filters” node. So we need to have the IIS_WPG group for filters node since we are using a custom identity and the user is part of IIS_WPG group.

  • Why the ISAPI filter gets invoked when the application pool identity is part of local admin group?

As shown in Figure 3 the “Administrators” group is part of the default permission list. So when ever you add the custom identity to local admin group the process identity gets the required privileges to invoke the ISAPI filter.

  • Why the ISAPI filter is invoked when the application pool identity is NETWORK SERVICE even though it is not part of Administrators group?

Again, as shown in Figure 3 the “NETWORK SERVICE” is explicitly added as part of the default permission list. So the ISAPI filter still gets invoked even though the NETWORK SERVICE is not part of the local administrators group or IIS_WPG group.

Last but not least, I was not able to see any thing in the process monitor even though the root cause of the problem ended up being a permission related issue.

Hope this was useful!