From time to time, you're probably called on to deploy a Web application that traffics sensitive information. The deployment includes installing the application on a hardened server in such a way that no other Microsoft IIS applications can access the application files. Doing so protects sensitive information from curious or malicious users of the applications that are hosted on the same server as the sensitive information. I've always argued that if an application requires such high security, it should be on its own server. However, circumstances abound in which administrators must install a highly secure application on a server that hosts many other applications.

For example, perhaps your company acquired another company and you're consolidating data centers—but politics require that one company's applications be strictly isolated from the other company's applications, even though they coexist on the same server. In some cases, a server that hosts a mission-critical application containing sensitive information is underutilized and other applications are assigned to the server as part of a server-consolidation effort. Whatever the case, let's presume that the task has fallen to you. You've been asked to deploy a highly secure application on an IIS server that hosts other applications. What questions and considerations do you think of as you devise your plan for implementing the highest degree of application isolation you can manage?

Isolation Considerations
I would suggest you advise your management that perfect application isolation is impossible on any existing IIS platform. In particular, application isolation in IIS 5.0 can only go so far because it wasn't designed with this kind of sandboxing in mind. Critical component and script engines, such as Macromedia's Cold Fusion, run in the inetinfo.exe process, which must run in the context of the System process identity. In this circumstance, high degrees of isolation simply aren't possible.

By default, in IIS 6.0, Web applications run in the security context of the built-in Network Service account. This context is a significant improvement over that of the System account, and this modification alone makes IIS 6.0 a far better choice for your Web server. With some attention to detail, you can achieve a high degree of application isolation on an IIS 6.0 server.

Enabling application isolation on an IIS server involves controlling the application's process identity and the user identity, along with expert use of NTFS permissions (Later, I discuss other technologies you can invoke, but these factors represent the core of application isolation.) Many IIS administrators have a good but incomplete picture of the details, and only one misstep can turn your best efforts into a "nice try" rather than a bull's-eye.

Impersonation and the Process Identity
From an IIS security perspective, you're always interested in the process identity that runs your applications. All applications have a process identity. For example, if you're logged on as Joe, and you launch notepad.exe, the program launches under the authority of Joe and has Joe's user rights and permissions. In general, services run with the privileges of the System account, administrative tools run with the elevated privileges of the Administrator account, and user programs such as Microsoft Office applications run with the privileges of the user who launches them. In all these cases, a program has a process identity, also known as a security context.

IIS is no different: IIS uses a host process (depending on the version of IIS) to run your Web applications. The host process accesses system resources by using its process identity. For example, IIS 6.0 uses a host process named w3wp.exe, which runs with the process identity of Network Service. However, if w3wp.exe always used Network Service to access files, NTFS-enforced user permissions would be irrelevant! Every file and executable would require permission only to allow Network Service to read, execute, or write (as required), and nothing else would be necessary.

Clearly, that scenario won't do. We need a higher degree of granularity to control permissions for users or groups. To achieve this goal, IIS doesn't use its process identity but rather "impersonates" the user by comparing the user's access token that was assigned during authentication with the NTFS permissions on the file. In this way, user permissions are enforced.

The authors of IIS built both IIS 6.0 and IIS 5.0 so that IIS will typically impersonate the user, but your Web application might be written in such a way as to bypass impersonation. In other words, a developer can write an application so that when IIS goes to access a system resource, it "reverts to self." That is, IIS checks system resource permissions against the process identity rather than the user identity.

Applications that require elevated privileges typically perform operations on the server that the user doesn't have permission to do. Suppose a user authenticates to the server and clicks on a form to create a new user. The application permits this action, even though the user doesn't have sufficient permissions to add users to the server. The application has reverted to the process identity (in this case, System, which of course can do whatever the heck it wants), created the new user account, then resumed normal operation. Should this application run in a process identity that can't create users on the server, the operation would fail. With this design, you don't need to give users elevated privileges on the server to perform specific administrative tasks.

Microsoft ASP.NET is an example of an application that doesn't always enforce impersonation. To enable impersonation, which I recommend (for applications that aren't using forms-based authentication), follow the instructions in the Microsoft .NET Framework Developer's Guide chapter "ASP.NET Impersonation" (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetimpersonation.asp).

Although ASP.NET lets you control impersonation with a switch in the .config files, it isn't so easy to determine whether compiled applications are impersonating normally. One clue is that the application doesn't work unless it runs in the context of the System account. If your developers or vendors insist on running an application in Low application protection mode on IIS 5.0 or assign the LocalSystem identity to the application pool that hosts the application in IIS 6.0, your application must require the privileged context, which is a good indicator that impersonation isn't in effect throughout.

Another way to determine whether an application is accessing files as the process identity or as the user is to use Sysinternals' Filemon.exe. This free utility shows all file access in real time on the server. You need only to deny Full Control rights on the file in question, run Filemon, and access the file to see Access Denied in the results column, along with the name of the user who accessed the file. Figure 1 illustrates this procedure.

In terms of application isolation, the process identity is essential. Suppose you have two applications—secure application and public application. If both applications run with the same process identity, a developer for the public application can upload a program that switches to the process identity. In this security context, the program running in the public application can now read all the Web site content from the secure application and even invoke applications that reside there. Your biggest threat in this regard lies with people who have the authority to upload and execute programs, particularly binary executables. Therefore, developers who have such access to public applications are the biggest threat. An outside attacker can achieve the same results if he or she can successfully execute an attack that leverages the public application's process identity. Buffer-overflow attacks are typical of this genre. An attacker can also place a Trojan horse on a developer's workstation and gain privileged access to the server, or leverage a socially engineered way to gain access. For these reasons, applications that must run in the context of the System or Administrator account can't be effectively isolated from each other.

Ideally, in your task of creating a sandboxed application, you can apply NTFS permissions to your Web content so that the process identities for the secure application and its users are the only security principals that can access the content. In other words, make sure your NTFS permissions don't permit access to the process identity of any other Web application. To create such a design, you have to understand all the process identities that IIS uses. With IIS 6.0, you can assign your secure application a unique identity easily enough—see the next section—but with IIS 5.0, you can use Table 1 as a guide. (The table also applies to IIS 6.0 when running in IIS 5.0 worker process isolation mode.)

Changing Process Identities
In IIS 5.0, when you're running a typical Web application, you'll encounter three process names, each with its own identity. Inetinfo.exe is the main process and runs in the context of the System process identity. IIS uses dllhost.exe when an application is set to run in Medium or High Application Protection in IIS Manager, and it runs in the context of the IWAM_servername user (which is created during the IIS installation). If you run ASP.NET applications, those applications run in a process named aspnet_wp.exe, which uses the ASPNET user as the process identity.

Running Web applications in Inetinfo with the System process identity presents a problem. If a buffer-overflow attack occurs (as in the case of Code Red and Nimbda), the attacker has access to the highest security privileges on the server.

Microsoft doesn't support running inetinfo.exe under the context of any account other than the System account. Also, although you can change the process identity of your ASP.NET applications, all your ASP.NET applications run in a single instance of aspnet_wp.exe. The best you can do with IIS 5.0 is use Component Services to adjust the IWAM identity for dllhost.exe. If you do so, you must also change the password in the metabase and in the local IWAM user account. These custom modifications complicate deployment, troubleshooting, and administration. As a result, and because of the dependencies of inetinfo.exe (running as System), you shouldn't consider IIS 5.0 for sandboxing applications.

Conjugating IIS 6.0 process identities is much easier than in IIS 5.0. By default, anything that you invoke on an IIS 6.0 server will run in the context of the Network Service account, except for Common Gateway Interface (CGI) applications, which run in their own process in the context of the user that invokes them. To assign a unique identity to any application pool that hosts your Web application, you can use the Identity tab on the pool's Properties dialog box, as Figure 2 shows.

Now here's the trick: The Network Service account is a member of a group found only in Windows Server 2003 with IIS 6.0 installed: the IIS_WPG group. The IIS 6.0 Help files state, "The IIS_WPG group provides the minimum set of privileges that are required by IIS, and it provides a convenient way to use a specific user for the identity account without having to manually assign the privileges to that identity. In cases where the account is not in the IIS_WPG group and does not have the appropriate permissions, the worker process will fail to start." This quote is inaccurate and misleading. In a nutshell, the identity assigned to the application pool—as you see in Figure 2—must be a member of the IIS_WPG group. It's not optional. You can't assign a user account all the necessary privileges because some of them are built in to the IIS_WPG group and its relationship to http.sys.

This fact has important implications if you're dealing with application isolation in IIS 6.0. Recall that the developer can control impersonation. Because all process identities (application pools) share membership in the IIS_WPG group, by default all Web applications can access any content on the server where NTFS permissions allow IIS_WPG access.

Your task is then straightforward but not obvious: You must assign a unique process identity to each application that you want to isolate, make the identity a member of the IIS_WPG group, and ensure that the NTFS permissions for the site content contain Read and Execute for the unique identity. You can't use groups such as Users, Everyone, Authenticated Users, and IIS_WPG on your Web site permissions because the unique process identities will be members of those groups.

Managing Permissions for IIS_WPG
Because we're trying to isolate applications as much as possible, anywhere the IIS_WPG group has privileges is a concern: By default, the IIS_WPG group has rights to several locations on the server, as Figure 3 shows.

As you can see, the IIS_WPG group has Full Control rights to the IIS Temporary Compressed Files folder. IIS uses this folder when compression is enabled in IIS Manager. Compression causes IIS to write compressed contents to the IIS Temporary Compressed Files location and deliver subsequent requests for the document from the cache. Only one IIS Temporary Compressed Files folder is in place for all Web sites, and according to the Microsoft article "Using HTTP Compression for Faster Downloads" (http://www.microsoft.com/resources/ documentation/IIS/6/all/techref/en-us/iisRG_PER_26.mspx), this folder must have Full Control rights for the IIS_WPG group. This information contradicts that of the Microsoft article "Default permissions and user rights for IIS 6.0" (http://support.microsoft.com/ kb/812614), which maintains that the defaults are List, Read, and Write. In fact, the IIS_WPG group does have Full Control rights.

For the purpose of application isolation, any location that gives Full Control rights to the IIS_WPG group is a threat. Your choices for managing compression in this environment are as follows:

  • Don't use compression. To ensure that compression fails, remove the IIS_WPG group from the permissions in the IIS Temporary Compressed Files folder.
  • Use compression only for the secured site. Remove the IIS_WPG group from the permissions in the IIS Temporary Compressed Files folder and assign Full Control rights to the unique user identity you've created for the application pool.
  • Use compression only for sites other than the secured site. The easiest way to do so is in the IIS Temporary Compressed Files folder: Deny Full Control to the process identity assigned to the application pool that hosts your secure application. With this configuration, all applications except the secured application can use compression.
  • It probably didn't escape you that the IIS_WPG group also has Full Control rights to the \%windir%\system32\inetsrv\ASP compiled templates folder. The Microsoft article "ASP Template Caching" (http://www.microsoft.com/resources/documentation/IIS/6/all/techref/en-us/iisRG_SCA_28.mspx) states that this location requires that the IIS_WPG group have only Read, Write, and Delete privileges, but in fact the group has Full Control. The documentation is also incorrect in the Microsoft article "AspDiskTemplateCacheDirectory" (http://www.microsoft.com/resources/documentation/WindowsServ/2003/ standard/proddocs/en-us/Default.asp?url=/resources/documentation/WindowsServ/2003/standard/proddocs/en-us/ref_mb_aspdisktemplatecache directory.asp), which states, "Typically, the identity of the processes running Asp.dll is the IWAM_USER and System accounts." This statement is clearly a reference to IIS 5.0 rather than IIS 6.0, because the IIS 6.0 default is Network Service.

    The good news is that the compiled templates location is configurable per site, folder, or virtual directory. As a result, you can create distinct ASP template cache locations with NTFS permissions assigned such that no other applications running on the site (other than those with Administrator or System privileges) can read or write to the template cache folder. The AspDiskTemplateCacheDirectory Metabase setting governs the location. Use Metabase Explorer or Adsutil to create this metabase setting, then assign it to a unique folder for your secured application. Grant Full Control rights to administrators and to the unique identity assigned to the secured application pool.

    When configuring for application isolation with ASP.NET, you have to properly configure permissions for temporary ASP.NET files. The IIS_WPG group has Full Control access to the \%systemroot%\Microsoft.NET\Frame work\v1.1.4322\Temporary ASP.NET Files location. Fortunately, you can specify the location for temporary ASP.NET files per application through the web .config file in the <compilation> element, as Microsoft's "ASP.NET Settings Schema" (http://msdn.microsoft.com/ library/default.asp?url=/library/en-us/ cpgenref/html/gngrfcompilation section.asp) describes. Doing so lets you isolate and secure this folder as required.

    Of course, those of you who aren't using ASP or ASP.NET will need to investigate where the IIS_WPG group has been given permissions in your scripting language or application and take appropriate action. If you find yourself in a situation in which the IIS_WPG group must have rights to a location for your application to function properly, and there's only one such location for the entire server, ensure that other applications on the server can't read or potentially modify the content of your secured applications in that location. As you've seen, such locations include temporary file caches but can also include common databases, configuration files, common binaries, and other content. The specifics entirely depend on your circumstances.

    You can use cacls.exe to output the permissions to a text file for study. The following is an example for the default IIS installation.

    cacls C:\inetpub\wwwroot\* /T > output.txt

    Managing Anonymous Access

    Finally, you'll need to create a unique anonymous user for your secured Web site. The user doesn't require any specialized privileges because a standard user account will have the necessary rights. Be certain to use a very strong password, and don't use "IUSR" in the account name—otherwise, you might confuse IIS about which is the default IUSR account and which is your creation.

    When you're assigning NTFS permissions, keep in mind that for your secured content, you can't use groups such as Users, Authenticated Users, and Everyone, unless you specifically deny anonymous users of other Web sites access to your entire content directory.

    Other Technologies and Considerations
    Application isolation often extends beyond the individual IIS server and onto other servers in the enterprise. The details about how you connect to network resources, the security context, services used, and authentication mechanisms all come into focus when your application reaches out to a database, file server, or other network device. These concerns are outside the scope of this article, but you might want to check into COM+ partitioning as introduced in "What Are COM+ Partitions" (http://msdn .microsoft.com/library/default.asp? url=/library/en-us/cossdk/htm/ pgservices_partitions_1gdb.asp) and constrained delegation as covered in "Kerberos Protocol Transition and Constrained Delegation" (http://www .microsoft.com/technet/prodtechnol/ windowsserver2003/technologies/ security/\constdel.mspx). Also, feel free to read my white paper, "Configuring Application Isolation on Windows Server 2003 and Internet Information Services (IIS) 6.0" (http:// www.microsoft.com/technet/prodtech nol/windowsserver2003/technologies/ webapp/iis/appisoa.mspx).

    Be Meticulous
    Deploying an application on an IIS server that must be as sandboxed as possible from other applications on the same server is a challenge. IIS 5.0 isn't well suited for this role because of a potpourri of process identities and mechanisms that control them. IIS 6.0 is much better suited. We can now control the process identity of application pools and manage NTFS permissions to achieve isolation. Isolating and securing any location that uses the IIS_WPG group requires precise thought, and you have to carefully apply NTFS permissions. However, a methodical approach can result in a high degree of isolation.45549

    Table 1: Process Identities and Applications in IIS 5.x and IIS 6.0 in IIS 5.0 Worker Process Isolation Mode

    Application Type

    Control Mode or Setting

    Process Name

    Process Identity

    Static Content

    Not configurable

    Inetinfo.exe

    System

    ISAPI Filters

    Not configurable

    Inetinfo.exe

    System

    ISAPI Applications

    Application Protection:

    (usually .dll)

    Low

    Inetinfo.exe

    System

    Medium

    Dllhost.exe

    IWAM_servername

    High

    Dllhost.exe

    IWAM_servername

    CGI (usually .exe)

    None

    Runs in own process

    Controlled by

    CreateProscessasUser Metabase setting; set to 1 (default), runs as the

    invoking user; set to 0, runs as System

    ISAPI Script Engines

    If listed in InProcessIsapiApp,

    Inetinfo.exe

    System

    in Application

    Otherwise Application

    Mappings

    Protection settings rule:

    Inetinfo.exe

    System

    Low

    Dllhost.exe

    IWAM

    Medium

    Dllhost.exe

    IWAM

    High

    ASP.NET Applications

    Machine.config

    aspnet_wp.exe

    ASPNET user

    process model element

    System

    userName=machine

    Specified User

    userName=System

    userName=username

    password=password

    Figure 3: Server locations to which IIS_WPG has permissions