ASP.NET 2.0 Configuration Lockdown

Little-known Security Improvements

Hundreds of significant improvements have been made inASP.NET 2.0, many of which help improve security. One of these improvements that has not received much attention (as of yet) are new options for administrators to lock down the ASP.NET configuration.

Microsoft s documentation and white papers always refer to Web hosting services when describing these features. As a result, you may have ignored them because you don t run a Web hosting service. They are actually quite useful in other environments, as well. They can be a boon to anyone wanting to delegate portions of the administration of an application server, while still maintaining security control. They are also highly useful in ensuring policy compliance, preventing configuration errors, and otherwise maintaining control over your Web server s behavior.

Most ASP.NET applications are deployed on Web servers side-by-side with other applications. A content management system, search function, and administration tools could all be separately developed ASP.NET applications that work together to form the entire Web site. In such an environment, some configuration settings will be shared and some will be unique to each application.

In corporate environments, these applications are often developed and deployed by different departments or groups. By locking down the ASP.NET configuration, the Web server administrator can ensure that all groups choose only secure configurations for their applications, while still allowing them freedom to configure non-security-relevant settings. Corporate policy for security and non-security settings can also be enforced centrally, ensuring compliance.


Background: ASP.NET Configuration

A review of the ASP.NET configuration system will be helpful to understand these options. Each application can have a web.config file, which specifies (using XML) the configuration settings for that application. Any settings not specified explicitly are inherited from the settings specified in the directory above. (Note that this inheritance is done using Web server virtual directories, not physical directories.)

At the top of the inheritance hierarchy is a central copy of web.config stored in the CONFIG subdirectory of the .NET Framework installation. Any settings not specified here will use default values coded into the framework. Normally, the settings in the framework directory are the sole province of the administrator of the system, since they can potentially affect every .NET application on the system. Conversely, the settings in an application s web.config are the province of the administrator of that application, and can only affect it and its subdirectories.

Configuration files contain many critical settings, including how authentication and authorization is handled, choices for cryptographic algorithms and keys, and sometimes even the credentials of administrators. It is important that control is maintained over these settings so that incorrect choices are not made. Poor choices within an individual application could compromise the security of the entire Web server.

The system administrator can set defaults based on corporate policy in the upper web.config files. But there must be a way to ensure that these choices are not altered within the local configuration of an individual application, in defiance of policy.

And indeed, ASP.NET 1.1 provided a means to do this. This is handled by the configuration element named , which is typically used as shown in Figure 1.





Figure 1: Sample ASP.NET tag.

Elements specified inside a element will apply only to the resource (a directory or individual file) specified in the path attribute. In the example in Figure 1, the application directory MyApplication has been locked to run at Medium trust. If that application has the element in its web.config, an exception will be thrown when the application starts and it will not run.

There are a number of problems with this scheme. They become immediately obvious to anyone who has tried to use it on a server with more than a handful of Web applications present.

First of all, it clutters the central configuration file with settings that are specific to an individual application. This breaks the modularity of the configuration system, and prevents some uses of the so-called XCopy deploy. Each time the application is redeployed using XCopy, the system administrator often must tweak the central configuration file to ensure settings are correct. This creates workflow issues that hamper your ability to delegate administration of the server.

Second, the semantics of the element, as a wrapper around the section-level element, causes problems. There are often default settings for each section expressed in the central web.config. The application-specific locks on these settings reside in a different spot in the file, in order to obey XML syntax. This forces you to look at several spots in the same file to get a full view of what the default for a given setting might be.

Third, this mechanism works only at the element level in XML, and does not offer attribute-level flexibility. Most configuration items in ASP.NET have many significant attributes, some as many as a dozen. If the system administrator locks an element in this way, the application administrator cannot alter any attribute on the affected element. An example will help illustrate.

Suppose corporate policy dictates that forms-based authentication only is used over SSL secured links, and that the authentication timeout be set to a maximum of 10 minutes. An administrator might try to enforce this policy using the settings found in Figure 2. They would quickly find that this does not work as expected.







Figure 2: Enforcing forms policy incorrectly.

You will notice that no path attribute is specified on the location element in Figure 2, which causes these settings to apply to all applications on the server. The problem is that there are about a dozen other attributes of the element, some of which are very application-specific, such as the location of the login form. All of those very application-specific attributes would have to go into the central configuration file in order for any part of it to be locked. This further exacerbates the modularity issue mentioned earlier.


.NET 2.0 Improvements

The designers of the .NET Framework were clearly aware of the limitations of the location element in .NET 1.1, and have added some significant new functionality in 2.0 to overcome these problems. The new functionality takes the form of new attributes that are inherited by all section elements in the .NET configuration schema. The new attributes are listed in Figure 3.







Figure 3: New Attributes in .NET 2.0.

If you ve ever edited your web.config using Visual Studio 2005, you may have noticed these attributes in the IntelliSense dropdowns.

The configSource attribute allows you to redirect an element to be drawn from a separate file, much like the file include functionality of many programming languages. The string value, of course, is a file name. This can be useful as well in delegation of administration, particularly if you need to sub-delegate some configuration issues within a given application. The way to implement this is to put the delegated configuration item in a separate file, and refer to it in the main web.config using configSource. Then, set the file system Access Control Lists (ACLs) to allow the appropriate persons or roles write access on each of the files. The rest of this article, however, will focus on the other attributes, the ones that begin with lock.

The lock attributes are the most interesting, and in general do exactly what their names suggest. Use lockItem to lock the current element and all of its children. Use lockAttributes or lockAllAttributesExcept to lock specified attributes of the current element. Use lockElements or lockAllElementsExcept to lock specified sub-elements of the current element. Other than lockItem, each of the attributes expects a comma-separated list of attribute names in its value.

There are a number of advantages to using the new lock attributes to secure your configuration. For one, you specify these directly on the element you wish to lock, and no longer have to use the enclosing location element. This makes the syntax for locking down an element much simpler in the central web.config. It also means you can specify default values that can be overridden, and default values which are locked, all in one place. Properly used, these attributes should reduce the clutter in your central web.config file.


Practical Examples

Some practical examples will help illustrate. First, let us correctly solve the problem shown in Figure 2. The new configuration elements would look like that shown in Figure 4.





Figure 4: Enforcing forms policy correctly.

Notice that the location element is no longer needed. Simply specify the elements and attributes desired and indicate which attributes to lock. All other attributes are open to change by the application administrator. Meanwhile, we can rest easy that timeouts and SSL will be configured the way corporate policy dictates.

A second example concerns modules and handlers. ASP.NET uses plug-in style architecture to add functionality to the framework. Two of the main places these are loaded are via the httpHandlers and httpModules elements in the configuration. There are many cases where an individual application might load an extra handler or module to achieve some functionality. For example, many URL redirection libraries for ASP.NET take the form of loadable httpModules.

In most cases, however, you should not allow applications to remove functionality from the initially loaded set. You may have a module loaded that provides essential security or logging functions, which you do not want disabled. Removing the HttpForbiddenHandler from a file extension like *.cs could cause the source code of your application to be disclosed to Web site visitors.

Like many other list elements in web.config, these two sections use sub-elements named add , remove , and clear to manipulate the list. To prevent removal of any of the stock handlers or modules, you should lock out use of both clear and remove . The syntax is shown in Figure 5.








Figure 5: Preventing removal of handlers and modules.


Implementing on a Production Server

You can lock down your server configuration by editing the top-level web.config. Take care when editing this file, as careless errors can completely disable ASP.NET on the server. It is always best to experiment in a testbed environment before rolling out changes.

You will notice that while in ASP.NET 1.1 most defaults were explicitly specified in the central configuration, this is not true in ASP.NET 2.0. Many elements of the configuration obtain their defaults internally and do not exist by default in the central web.config.

In cases like this, you will have to add the appropriate XML to your central web.config, making your chosen defaults explicit. Often the syntax to express the framework defaults is included in the relevant MSDN article. Make sure you put it in the appropriate point in the XML hierarchy of web.config; most settings reside inside the system.web element. Alter the default values to express your corporate policy, then add the attributes you need to lock each section.

When testing, watch for telltale configuration error messages. This exception occurs before any of the application code executes, when the web.config is initially parsed. Figure 6 shows what the standard ASP.NET error message shows when an attempt to unload a module has been blocked using the example shown earlier.

Figure 6: Locked configuration error message.

Be aware that changing the defaults for some settings can cause particular applications to malfunction. Thorough testing is always recommended.

One limitation of the lock attributes will become obvious as you make changes. When you lock a setting, any attempt to touch that setting, even to set the same value as the locked one, will cause a configuration error. So in the process of locking down your server, you may have to scrub your applications web.config files of any reference to attributes that you are choosing to lock.

Of course, it is implied that if any effort to touch a locked setting will fail, an application cannot choose a more restrictive setting than the one that is locked by the administrator. For example, if you have locked all applications to Medium trust, an individual application cannot put itself on Low trust. Any override of a locked setting must be done using the location element in the web.config where it is locked. Consider the example shown in Figure 7.










Figure 7: Locking defaults and overriding for one application.

In Figure 7, forms authentication policy has been set for 10-minute timeouts and SSL only, and the defaults are locked. However, this policy is overridden for a single application named Special . Otherwise, applications will not be allowed to alter these defaults. Note that it is not necessary to specify the lock attributes on the location override, they still apply from the default.

When choosing which elements to lock down, carefully consider your corporate policies and the various best practices documents on ASP.NET. The Patterns & Practices section of MSDN has many documents that make excellent suggestions. Again, every configuration change has implications in the behavior of your applications, so you should read the guidelines carefully and always test, test, test.

As a quick reference, Figure 8 shows a list of top-level elements within that are worth considering locking for security reasons.


What you should consider locking


Lock attribute level to Medium or below.

Running under reduced trust helps ensure any attack can only have a limited effect on your server.

Lock entire item; make sure it is empty.

Credentials should only be used for testing; use an ASP.NET membership provider in production.

Attribute passwordFormat to MD5 or SHA1 .

If you must use credentials in production, then ensure that passwords are not stored in the clear.

Lock entire item. Make sure HttpPost and HttpGet are not enabled, and consider removing Documentation as well if not needed.

HttpGet (and to a lesser extent HttpPost) can be used in some luring attacks. Documentation is only needed if you allow third-parties to use your Web services freely.

Lock attribute href, and point it at a generic error page or the top page of your site.

Prevents attackers scanning your site from easily obtaining information about how your Web services work.

Lock attribute retail to true .

Ensures that custom errors, tracing, and debugging are set to secure values.

Lock elements and .

Ensures your desired modules are loaded in all applications; still allows additions.

Lock elements and .

Ensures your desired handlers stay in effect. In the case of the forbidden handler, this can avoid unintentional source code disclosures.

Lock attribute validateRequest to true .

Ensures that requests are validated against potential cross-site scripting input.

Lock attributes enableViewStateMac to true and viewStateEncryptionMode to Auto or Always .

Minimizes the possibility of one click attacks using view state.

Lock attribute userIsOnlineTimeWindow to desired value.

Minimizes the window for cookie theft attacks.

Lock attributes httpOnlyCookies and requireSSL to true .

Minimizes the opportunity for cookie theft attacks. Note: SSL setting is default that can be overridden by , , and elements. You must lock it in all four places to ensure that all cookies are secured by SSL.

Lock attributes requireSSL to true , protection to All , cookieless to UseCookies and timeout to desired value.

Minimizes the opportunity and window for cookie theft attacks.

Lock attributes cookieRequireSSL to true , cookieProtection to All , cookieless to UseCookies and cookieTimeout to desired value.

Minimizes the opportunity and window for cookie theft attacks.

Consider locking attributes cookieProtection to All , cookieRequireSSL to true , and cookieTimeout to desired value.

Minimizes the opportunity and window for cookie theft attacks.

Lock attribute enableHeaderChecking to true , enableVersionHeader to false , and maxRequestLength to as small a value as practical.

Helps prevent denial of service attacks against the server.

Figure 8: ASP.NET configuration elements to consider locking.

The new locking elements in .NET Framework 2.0 provide an excellent way to control the configuration of your Web server, while still allowing administration of individual applications to be delegated to others. They avoid the pitfalls of the location tag from earlier versions of .NET, and allow you a great deal of granularity and control.

With that said, these locking controls are by no means a security panacea. All deployed Web applications should be carefully audited for configuration errors and other security problems, as part of your secure development lifecycle.

But locking down critical configuration items centrally provides an additional safeguard and becomes part of your defense-in-depth strategy. This is an excellent tool for any ASP.NET administrator to have in their toolbox.


Tim Farley is a senior software engineer for SPI Dynamics and a researcher for the company s renowned R&D team, SPI Labs. Tim is responsible for researching new techniques to secure Web applications as they are developed and deployed. Tim came to the IT security industry via his expertise in reverse engineering of software, which he has been doing for over 20 years. He is a published author, has contributed code to open source software projects, and has participated in standards committee work with the IETF. Tim has also testified as an expert witness on reverse engineering in Federal court.

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.