In previous versions of IIS, it has sometimes been difficult to isolate web application pools from each other. If multiple web application pools are configured to run as the same identity (e.g. Network Service) then code running inside one web application pool would be able to use File System objects to access configuration files, web pages and similar resources belonging to another web application pool. This was because it was impossible to allow one process running as Network Services access to a file, but prevent another process also running as Network Service access to the same file.

In IIS 7.0 it is possible, with some work, to prevent this from occurring. As part of IIS 7.0 inbuilt functionality, each web application pool has an application pool configuration file generated on-the-fly when that application pool is started. These are stored, by default, in the %systemdrive%\inetpub\temp\appPools folder. Each web application pool has an additional SID (Security Identifier) generated for it, and this in injected into the relevant w3wp.exe process. The application pool's configuration file is ACLed to allow only that SID access. Since each w3wp.exe process has it's own SID, each application pool's configuration file is ACLed to a different SID:

IIS Application Pool Isolation

Using the icacls.exe tool it is possible to determine the SID applied to any given application pool's configuration file. This can be done by using the command:

icacls.exe %systemdrive%\inetpub\temp\appPools\appPool.config /save output.txt

The actual SID always starts with the well-known identity prefix: S-1-5-8-82 followed by a hash of the Application Pool's name.

The retrieved SID can now be used to secure web site content in the same way. To do this:
Edit: Thomas Deml (from the IIS Product Group) has shown me an easier way to perform Step 4 below

  1. Configure each website (or web application) to run in its own web application pool
  2. Configure anonymous authentication to use the application pool identity rather than the IUSR account (this can be done by editing the Anonymous Authentication properties for the website in question)
  3. Remove NTFS permissions for the IUSRS group and the IUSR account from the website's files and folders.
  4. Use the icacls.exe tool to permit the App Pool's individual SID Read (and optionally Execute and Write) access to the web site's files and folders. You don't need to initially retrieve the SID using iCacls. Instead simply use: IIS APPPOOL\ApplicationPoolName as the user to grant read permissions to (see screenshot below for an example for the Default App Pool)

After configuring these NTFS permissions, only the SID that has been injected into a particular w3wp.exe process will be able to read the contents of the website in question. All code running in other w3wp.exe processes, even though the process identity may also be Network Service, will be unable to read this particular website's content. This technique may be most useful to web hosters or similar administrators, that need to accept content from various external or untrusted parties.

Edit #2: Here's a screenshot of the dynamic SID injection in action for the Default App Pool (using the excellent Process Explorer tool). The username highlighted can be used with icacls.exe to ACL your web content.

IIS 7 App Pool Isolation - Dynamic SID injection