Web applications and XML web services developed using ASP.NET are the means through which many companies provide information and services to their customers and partners. The very nature of these services demands that they be accessible usually located at the edge of the corporate network and consequently reachable by anyone with an Internet connection. To be of value, these services must be available and reliable, meaning that authorized people can use them when they need to, without concern that the service will crash or behave unexpectedly. In addition, depending on the service and the type of data it processes, there may be a requirement (or possibly a legal obligation) for the service provider to ensure that the data produced by, or stored within, the service remains secure and secret.
Unfortunately, the reachability of ASP.NET applications, coupled with their propensity to represent useful, valuable, or at least mildly interesting functionality, means that ASP.NET applications are more likely to be the target of security attack than other applications that you develop. These attacks aim to bring down the service, change its functionality, or gain access to valuable data or services. In addition, given that ASP.NET applications often represent one of the few points of presence a company has on the Internet, attackers may try to use the ASP.NET application as a gateway through which to gain access to the corporate network behind, which usually contains even more valuable and useful information.
18.1.1 ASP.NET Security Overview
ASP.NET provides a framework that dramatically simplifies the development of web applications (including XML web services) and provides a rich set of commonly required services that programmers would otherwise have to implement themselves. These services include state management, caching, and device-independent UI generation. From a security perspective, ASP.NET provides services to support user authentication, authorization, and impersonation.
ASP.NET successfully abstracts the complex development issues associated with implementing many of its shared services, and exposes them through a mixture of simple object models, configuration settings, and declarative program statements. As such, implementing security in ASP.NET applications is more an issue of configuration than programming.
Fortunately, despite the efforts to provide a simplified development model, ASP.NET remains flexible. ASP.NET applications are .NET applications that run in the CLR. Programmers can still write ASP.NET applications in both C# and Visual Basic .NET and have access to the full capabilities of the .NET class library. This includes access to all of the security classes we discuss elsewhere in this book.
Because ASP.NET applications run in the CLR, they are constrained by the permissions granted to them by CAS, which we discussed in Chapter 5 through Chapter 9. Initially, it may seem odd to use CAS (usually aimed at controlling the action of mobile code) to control the actions of server-based applications. However, if you have a server that hosts ASP.NET applications produced by different companies, CAS will allow you to give each company the freedom to manage its own application, while ensuring that the code it uploads cannot affect the host server or the applications of other companies. In addition, should hackers manage to gain control of an application, their actions will be constrained by the permissions assigned to the application by CAS, limiting the damage they can do.
18.1.2 ASP.NET Configuration Files
ASP.NET uses XML-based configuration files as a simple and convenient mechanism through which to configure elements of application operation. This includes important security settings, such as the user authentication mechanism to use and the code-access security policy to apply to an ASP.NET application. We discuss all of these security settings later this chapter, but first it is important that you understand how ASP.NET configuration files work.
ASP.NET implements a hierarchically configurationed file structure. As with all .NET applications, the main source of configuration information is the machine.config file, which is located in the CONFIG folder of the .NET Framework installation directory. The machine.config file provides a central location in which you can implement configuration settings that apply to all ASP.NET applications running on the machine.
Each folder in an ASP.NET application's virtual path can contain a configuration file named Web.config, which provides configuration settings for the application resources located in that folder. Child folders inherit the configuration of their parent folder, meaning that configuration settings cascade down through an application's virtual folder hierarchy. However, child folders can also contain their own Web.config; the settings contained in this file override those configured higher up in the folder hierarchy.
To illustrate the behavior of configuration files, consider the folder hierarchy in Figure 18-1, which shows a fictitious representation of the web site http://www.oreilly.com. The site contains a virtual folder named DotNetSecurity used to contain sample applications from a book. The samples are divided by chapter, and below that, each sample application is in its own folder (App1, App2, and so on); each application directory is configured as an IIS application root. Application roots play an important role in ASP.NET application configuration; though Web.config files can appear anywhere in the ASP.NET application folder hierarchy, there are many settings that cannot be applied below the level of an application root folder.
Figure 18-1. ASP.NET configuration file hierarchy
In Figure 18-1, the machine.config file resides at the top of the configuration hierarchy, and its settings apply to all folders in the hierarchy below it unless they are overridden. The top-level DotNetSecurity folder contains a Web.config file, which will apply to all resources in all of the folders below it; this includes the Chapter17 and Chapter18 folders and all of their child folders. Both of the App1 and App2 folders have their own Web.config files. The Info folder contains no Web.config file and is subject to the configuration settings specified in the following configuration files:
184.108.40.206 ASP.NET security-related configuration elements
ASP.NET configuration files contain settings that affect many aspects of the ASP.NET application. We list the most important security-related configuration elements in Table 18-1 along with a brief description. Each of the configuration elements listed are children of the <system.web> element, except for the <location> element, which is a direct child of the root <configuration> element. The result is the structure shown in the following listing. For a complete list of all ASP.NET configuration elements, consult the .NET Framework SDK documentation.
<configuration> <location/> <system.web> <authenticaiton/> <authorization/> <identity/> <machineKey/> <processModel/> <securityPolicy/> <trust/> </system.web> </configuration>
220.127.116.11 Using <location> elements
Normally, the configuration settings contained in a Web.config file apply to all of the resources contained in the folder where the Web.config file is located, as well as all child folders. The <location> element allows you to target configuration settings at a specific folder or resource. Specify the target of the configuration settings in the <location> element's path attribute.
The <location> element is commonly used in conjunction with the <authorization> element to control access to individual resources (we discuss the specifics of the <authorization> element in Section 18.4 later in this chapter). In the following Web.config located in the DotNetSecurity folder in Figure 18-1, we specify that only members of the Admins role can access the Chapter17 folder and only members of the Developers role can access the Chapter18/App2/Main.aspx file. Notice that a separate <location> element encapsulates each set of configuration settings.
The allowOverride = "false" attribute of the first <location> element means that the configuration settings cannot be overridden in the Web.config files of child folders. This is a critical feature in order to manage the security configuration of ASP.NET applications, especially in a hosted environment where different companies have the ability to upload their own ASP.NET applications and configuration files:
<configuration> <location path="Chapter17" allowOverride="false"> <system.web> <authorization> <allow roles="Admins"/> <deny users="*"/> </authorization> </system.web> </location> <location path="Chapter18/App2/Main.aspx"> <system.web> <authorization> <allow roles="Developers"/> <deny users="*"/> </authorization> </system.web> </location> </configuration>
If you apply the allowOverride = "false" attribute setting to a <location> element that does not specify a path, it will completely disable the ability for Web.config files in child folders to override any configuration settings. For example:
<configuration> <location allowOverride="false"/> </configuration>