Skip navigation

Take Control of the ASPNET Account

Learn more about the ASP.NET security context.





Take Control of the ASPNET Account

Learn more about the ASP.NET security context.


By Dino Esposito


ASP.NET performs a sequence of tasks - dubbed collectively the ASP.NET process model - aimed at servicing a client request. Currently, ASP.NET supports two models - the default model and the IIS 6 model - and their use depends on your operating system and how IIS is configured. The default model used on Windows 2000 and Windows XP with IIS 5.x is based on an ISAPI extension and an ASP.NET-specific worker process (aspnet_wp.exe) that hosts the Common Language Runtime (CLR). This model also is used on Windows Server 2003 when IIS 6.0 is configured to run in compatibility mode. But the normal mode of operation of IIS 6.0 on Windows Server 2003 is known as the IIS 6 process model, and it consists of an ISAPI extension and an IIS worker process (w3wp.exe). Within this process, the request goes through an ISAPI extension, which loads the CLR in the process and activates the HTTP runtime pipeline. With IIS 6.0, IIS manages ASP.NET and no longer concerns itself with tasks such as process recycling, gardening, and isolation from the Web server. Although key differences exist between the two process models, they both leverage a couple of components - an ISAPI extension, and a worker process that hosts the CLR and runs managed code. The interaction of these two components determines how the ASP.NET subsystem works as well as its security settings.


In this article, I'll focus on the security context in which ASP.NET requests are served. The security context in which the ASP.NET runtime operates is affected by privileges and permissions set on the components of the ASP.NET process model. I'll refer mostly to the default IIS 5.x process model, and I'll signal any relevant differences in the IIS 6 process model.


Serve the Request

When a request hits IIS, the Web server first ensures that the request comes from a trusted IP address. If not, the request is rejected with the 403.6 HTTP error; if the requested resource belongs to a protected type, such as .asax files, IIS returns an HTTP error 403.2. If the resource can be accessed, IIS attempts to authenticate the caller using Windows' Integrated, Digest, or Basic authentication methods. Which method is used depends on how IIS is configured. To handle the request, IIS picks up a thread from its pool and gives it the identity of the authenticated user; if anonymous access is performed, the IIS thread has the anonymous identity. The thread now does its job and dispatches the request to the ASP.NET ISAPI extension.


The ISAPI extension, named aspnet_isapi, is hosted by the IIS process and therefore runs under the SYSTEM account. The ISAPI extension is a piece of unmanaged code responsible for starting up the ASP.NET worker process. The extension must guarantee that the worker process is available and healthy, and it sends requests to the process for processing. The ISAPI extension and the worker process communicate through a set of named pipes (see Figure 1). In particular, synchronous pipes are used for callbacks from the worker process into the ISAPI extension to retrieve some server variables and obtain information from IIS. Asynchronous named pipes are used for transporting requests and responses to and from the worker process.


Figure 1. The ASP.NET ISAPI extension hosted by IIS forwards the HTTP request to the ASP.NET worker process using a set of asynchronous named pipes. Then the request is processed through the ASP.NET managed HTTP pipeline.


The ISAPI extension has its own pool of threads, but it uses them only for asynchronous calls to the worker process. The extension does not process the HTTP request. The worker process receives the request to process along with the security token of the authenticated, or anonymous, IIS user. By default, the worker process runs under the ASPNET account.


The thread within the worker process that picks up the request inherits the identity token of the IIS thread. If impersonation is disabled, the thread runs under the account of the parent process - the ASPNET account. In the IIS 6 process model, the account of the worker process (w3wp.exe) is a built-in account named NetworkService.


Get to Know the ASPNET Account

The ASPNET account is a local account created when the .NET Framework is installed (see Figure 2). Unlike SYSTEM, which is the default account for classic ASP applications, ASPNET has few privileges: Access this computer from the network, Deny logon locally, Deny logon through Terminal Services, Log on as a batch job, and Log on as a service. ASPNET also has some NTFS permissions to operate on certain folders and create temporary files and assemblies, including access to the root of the .NET Framework installation folder, the "Temporary ASP.NET Files" directory, the global assembly cache (GAC) folder, and the Windows system directory.


Figure 2. Here is the Properties dialog box of the ASPNET user account. The account is created when the .NET Framework is installed, and its password is generated automatically and stored in the Windows local security authority.


Let's review some common scenarios that involve the ASP.NET system security context as opposed to the ASP.NET application security context, which is the context in which you use your own code to authenticate and authorize users.


To create or edit a local file, the worker process thread serving the current request requires access to the file or the containing folder. The thread runs within the context of the aspnet_wp process (ASPNET account) and impersonates an identity only if impersonation is on, which by default is false. If impersonation is enabled, the thread might impersonate the account propagated by IIS or IUSR_Machine in case of anonymous access; if the thread has an identity token, the token must provide write access to the file. By default, ASP.NET applications don't impersonate accounts and are accessed by the anonymous user frequently. In this case, the worker process thread inherits no identity and uses that of the host process - ASPNET. Because ASPNET could have no write permissions on the Web space, an exception is thrown if you try to create or edit a file.


A nearly identical situation occurs if your Web application attempts to open a connection to a database. In this case, you need a login defined for ASPNET or the identity being impersonated.


If a new process is to be created, it will inherit the account of the parent process. The new process will run under the ASPNET account whether or not impersonation is set.


The limited set of privileges granted to the ASPNET account helps fend off revert-to-self attacks. This is a typical attack a hacker can conduct once accessing your Web application (for example, exploiting a buffer overrun) simply by reverting the security token of the impersonated client to the token of the parent process. In ASP.NET, the most a hacker can obtain is the ASPNET account - the "weak" account of the worker process. Bear this in mind if you decide to change the default account for the ASP.NET worker process.


Change the Process Account

The base identity for the ASP.NET ISAPI extension is set to the account of IIS (SYSTEM) and is not configurable. The base identity for the ASP.NET worker process by default is ASPNET, but you can change it to any other system- or user-defined account (including SYSTEM). Information about the process account is set in the section of machine.config. Here are the default contents:



Setting the userName attribute to Machine indicates the default account - ASPNET or NetworkService if the IIS 6 process model is enabled. Setting the password attribute to AutoGenerate indicates that the password is generated cryptographically during setup. The password is stored in the Local Security Authority (LSA) of the operating system. You can configure the worker process to run under the SYSTEM account, although this approach is highly discouraged. Here's how you can give administrative privileges to your Web application:



You also can set an arbitrary Windows account by indicating the username and password:



Do not take lightly the decision to change to the default account - you must review a few aspects carefully. In particular, the new ASP.NET account shouldn't be less powerful than ASPNET; otherwise you seriously risk tearing down some ASP.NET functionality. At a minimum, you should guarantee that the new account is granted full access to the Temporary ASP.NET Files folder. You can set the section only within the machine.config file, and this affects all applications running on the machine. To mitigate this problem, you can apply settings to a specific resource by using a tag with an appropriate path attribute. You can use the path attribute to identify a specific file or folder to which unique configuration settings apply.


In addition, you should note that settings in the section are read by aspnet_isapi.dll, not by managed code. For this reason, changes to are not applied until IIS is restarted. Also, be aware that when you use the IIS 6 process model, the settings in the section are ignored. To configure the process identity (or other process model values), use the Configuration Manager and apply changes in the IIS metabase directly.


When you change the process account, you need to indicate the password in a clear text file, which never is a safe practice. In ASP.NET 1.1, you can encrypt and store usernames and passwords in the registry and link them to the .config files. This feature has been extended to ASP.NET 1.0 with Service Pack 3. In the .config file, you can indicate usernames and passwords like this:


userName="registry:HKLM\path\key, user"

password="registry:HKLM\path\key, pswd"


You indicate the path of the registry where the information is stored. A new utility, aspnet_setreg.exe, is provided with SP3 and ASP.NET 1.1 to encrypt and store credentials in the registry. Note that you can use this encrypting feature only for the , , and sections.


Enable Impersonation

Unlike classic ASP, ASP.NET works with impersonation disabled by default. This setting is configurable, however, and you can enable impersonation by editing this line in the web.config file:



Because the web.config file can be defined in each child folder, you could configure the application so it assumes different identities in different folders. This feature also depends on the fact that you can set the section at all levels of the configuration hierarchy - not only at the machine or application root level.


When impersonation is enabled, the thread processing the request can have a different identity from the ASP.NET process. In particular, the thread's security token is any token IIS uses to accept the request. The identity is that of the currently logged-on Windows user. Note that editing the section really is the only way to change the identity of the worker process. This is different from impersonating the current, or a fixed, user. If you change the identity of the process, all threads will use the new identity and no extra work is needed on thread switches.


An alternative to default impersonation is to impersonate a specific user by providing its username and password:


userName="..." password="..." />


This case deserves a bit of attention. To impersonate a user in Windows 2000, a process needs to call the LogonUser Win32 API. But this function requires an administrator-level privilege - the SE_TCB_NAME privilege - set on the calling process. In reality, the privilege does not need to be enabled, but it must be granted; the LogonUser function enables it if necessary. If the calling process does not have this privilege, the LogonUser function simply fails. What does this mean to you? If you want to support impersonation by name, you must grant the ASP.NET worker process a critical privilege. The default ASPNET account doesn't have such a privilege; as a result, you can't impersonate accounts in Windows 2000 unless you replace the ASPNET account with a stronger one that boasts the SE_TCB_NAME privilege. For this reason, impersonating by name in ASP.NET 1.0 might be dangerous. In Windows XP and Windows Server 2003, the SE_TCB_NAME privilege is no longer needed to log on as a particular user.


In ASP.NET 1.1, the situation is a bit different regardless of the underlying operating system. Even if the privilege is not granted to the worker process, impersonation by name still is supported by virtue of a smart trick. In ASP.NET 1.1 on Windows 2000, in fact, the aspnet_isapi, which runs under SYSTEM, creates the token and copies it back to the memory of the worker process. As a result, the weak ASPNET account impersonates any fixed identity.


ASP.NET counts three different security layers. One is represented by the worker process, which by default runs under a weak account such as ASPNET. The second layer is the security context of the thread within the worker process that actually serves the request; this token is affected directly by impersonation settings. Finally, the last layer of the ASP.NET security is the application-specific infrastructure for authentication and authorization. Interspersed between these three layers are many system features that have been improved significantly in ASP.NET 1.1 to make the runtime more secure.


Dino Esposito is a trainer and consultant who specializes in ASP.NET, ADO.NET, and XML. Author of Building Web Solutions with ASP.NET and ADO.NET and Programming Microsoft ASP.NET, both from Microsoft Press, Dino also is a co-founder of E-mail him at mailto:[email protected].


Tell us what you think! Please send any comments about this article to [email protected]. Please include the article title and author.




Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.