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.
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.
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.
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 "http://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