Configuring Application Pool Identity in IIS 6.0

Applies To: Windows Server 2003, Windows Server 2003 with SP1

When you run IIS in worker process isolation mode, applications can be configured to run in separate application pools. An application pool is a configuration that links one or more applications to a set of one or more worker processes. The application pool identity is the name of the account under which the worker process of the application pool runs.

Important

This feature of IIS 6.0 is available only when IIS is running in worker process isolation mode.

In earlier versions of IIS, worker processes ran as the LocalSystem account. Because the LocalSystem account has access to almost all resources of the operating system, this had serious security implications. IIS 6.0 strengthens security because the worker process runs under the new built-in Network Service account by default. IIS 6.0 also allows you to configure the account under which worker processes will run. You have the option of using one of the following three predefined accounts, or creating your own account:

  • Network Service. By default, application pools run under the Network Service user account, which has low-level user access rights, so it provides better security against attackers or malicious users who might attempt to take over the computer on which the WWW service is running.

  • Local Service. The Local Service user account also has low-level access rights, and is useful when you want to configure application pools to run as the Local Service user account in situations that do not require access to resources on remote computers.

  • LocalSystem. You can configure application pools to run as the LocalSystem user account, which has more user rights than the Network Service or Local Service user account. However, running an application pool under an account with increased user rights presents a high security risk.

For example, suppose an ISP wants to allow customers to upload CGI applications and then add them to an application pool. The ISP can run CGI-enabled applications in a separate application pool under the Network Service user account, which has lower user rights, to reduce the risk that these applications will be used to attack the server.

IIS_WPG Group

The IIS_WPG user group is new in IIS 6.0. It provides the minimum set of privileges and permissions required to start and run a worker process on a Web server. On a clean installation of IIS 6.0, the IIS_WPG group contains the Network Service, Local Service, LocalSystem, and IWAM_ComputerName accounts.

To designate a specific user account as a worker process identity for a Web site, make the user account a member of the IIS_WPG group. This is a convenient way to configure a custom identity for a worker process without manually assigning privileges and permissions.

All worker process identities must be members of the IIS_WPG group. If the worker process identity is not in the IIS_WPG group and does not have the appropriate privileges and permissions, the associated worker process will not start. In addition, the worker process identity might not be able to launch a worker process after a modification to the operating system, such as an upgrade or service pack.

Note

By default, the IIS_WPG group does not have the right to start CGI processes. If you create a configurable account and add it to the IIS_WPG group as a worker process identity, you must also assign this new account the following two user rights to start CGI processes: Adjust memory quotas for a process and Replace a process level token.

When you install IIS 6.0, the setup process adds an ACL to the wwwroot directory of the default Web site. This ACL gives the IIS_WPG group permission to access that directory, which means that all worker process identities in the IIS_WPG group can access the contents of this directory on the default Web site. However, you should not give this group access by ACLs to content for a specific Web site. Instead, to isolate applications, do one of the following:

  • Remove the IIS_WPG group from ACLs on site content.

  • Allow access to a Web site's content directories and files by providing ACLs for the worker process identity associated with the Web site, rather than for the IIS_WPG group.

  • If you create a configurable account to use as the worker process identity, add that account to any ACLs on the site's content directories and files.

For information about changing the account under which an application pool runs by using IIS Manager, see Configuring Application Pool Identity with IIS 6.0.

You can change the worker process identity programmatically by using the Microsoft® Visual Basic® Scripting Edition (VBScript) development system sample script provided in Listing 5.2. Listing 5.2 provides a customizable VBScript-based file that creates an application that runs in an application pool under the supplied identity. Then the script starts Task Manager to show the worker process, and it attempts to access the newly created application using Internet Explorer. When the script is complete, you should see, in Task Manager, a new worker process that serves the request and that runs under the supplied identity.

Listing 5.2   Sample Script for Configuring Worker Process Identity

' VBScript source code
option explicit

if WScript.Arguments.Count < 4 OR WScript.Arguments.Count > 5 then
   WScript.Echo "Usage:"
   WScript.Echo WScript.ScriptFullName & " username password AppPoolName vdirname <physical path for vdir>"
   WScript.Quit
end if 
dim basepath         :   basepath = "IIS://localhost/w3svc/1/root"
dim username         :   username = WScript.Arguments(0)
dim password         :   password = WScript.Arguments(1)
dim AppPoolName      :   AppPoolName = WScript.Arguments(2)
dim vdirname         :   vdirname = WScript.Arguments(3)
dim VDirPhysicalPath

if WScript.Arguments.Count < 5 then
   VDirPhysicalPath = "c:\inetpub\wwwroot"
else
   VDirPhysicalPath = WScript.Arguments(4)
end if

if CreateNewUser(username, password) = false then
   WScript.Echo "Error creating user " & username & ". "
   WScript.Quit
end if 

if AddUserToIIS_WPG(username) = false then
   WScript.Echo "Error adding user " & username & " IIS_WPG. "
   WScript.Quit
end if

if CreateNewAppPool(username, password, AppPoolName) = false then
   WScript.Echo "Error creating AppPool " & AppPoolName & " running as user " & username & ". "
   WScript.Quit
end if 

if CreateNewVDir(vdirname, vdirphysicalpath) = false then
   WScript.Echo "Error creating new virtual directory " & vdirname & ". " 
   WScript.Quit
end if 

if AssignAppPool(vdirname, AppPoolName) = false then
   WScript.Echo "Error assigning Application Pool " & AppPoolName & " to vdir " & vdirname & ". "  
   WScript.Quit
end if

dim wsh : set wsh = CreateObject("WScript.Shell")
WScript.Echo "Waiting for iisreset to return"
wsh.Run "iisreset /restart",,true
wsh.Run "https://localhost/" & vdirname
wsh.Run "taskmgr"

function AssignAppPool(vdirname, AppPoolName)
   dim vdirobj
   
   set vdirobj = GetObject(basepath & "/" & vdirname)
   vdirobj.AppPoolId = AppPoolName
   vdirobj.SetInfo
   if err = 0 then
      AssignAppPool = true
   else
      AssignAppPool = false
   end if 
end function

function CreateNewVDir (vdirname, vdirphysicalpath)
   dim VdirObj, VRoot
   set VRoot = GetObject(basepath)
   set VdirObj = VRoot.Create("IIsWebVirtualDir", vdirname)
   VdirObj.AccessRead = True
   VdirObj.AccessScript = True
   VdirObj.Put "Path", vdirphysicalpath
   VdirObj.SetInfo
   
   vdirobj.AppCreate true
   vdirobj.SetInfo
   if err = 0 then
      CreateNewVDir = True
   else
      CreateNewVdir = false
   end if
end function

function CreateNewAppPool(username, password, AppPoolName)
   dim AppPools, newAppPool
   set AppPools = GetObject("IIS://localhost/w3svc/AppPools")
   set newAppPool = AppPools.Create("IIsApplicationPool", AppPoolName)
   newAppPool.WamUserName = username
   newAppPool.WamUserPass = password
      newAppPool.LogonMethod =1 
   newAppPool.AppPoolIdentityType=3
   newAppPool.SetInfo
   if err = 0 then
      CreateNewAppPool = True
   else
      CreateNewAppPool = false
   end if
end function

function AddUserToIIS_WPG (username)
   dim nw : set nw = CreateObject("WScript.Network")
   dim computername : computername = nw.Computername
   dim MyUser
   dim IIS_WPG
   
   set IIS_WPG = GetObject("WinNT://" & computername & "/IIS_WPG,group")
   set MyUser = GetObject("WinNT://" & computername & "/" & username & ",user")
   if not IIS_WPG.IsMember(MyUser.AdsPath) then
      IIS_WPG.Add(MyUser.AdsPath)
   end if
   if err = 0 then
      AddUserToIIS_WPG = True
   else
      AddUserToIIS_WPG = false
   end if
   
end function   

function CreateNewUser(username, password) 
   dim nw             :   set nw = CreateObject("WScript.Network")
   dim computername   :   computername = nw.Computername
   dim container      :   set container = GetObject("WinNT://" & computername)
   dim newuser        :   set newuser = container.Create( "user", username)
   newuser.SetPassword(password)
   newuser.SetInfo
   if err = 0 then
      CreateNewUser = True
   else
      WScript.Echo "Error: " & err.Description & " - " & err.number
      CreateNewUser = false
   end if
   
end function