Friday, April 17, 2009

Application Security Vulnerabilities in Web.config File

The biggest threat to an organization’s network security comes from its public Web site and the
Web-based applications found there. As networks have become more secure, vulnerabilities in Web applications have inevitably attracted the attention of hackers who have techniques to exploit these holes.

Some of the most common and dangerous application security vulnerabilities that exist in ASP.NET Web-based applications come not from the C# or VB.NET code that make up its pages and service methods, but instead from the XML code that makes up its Web.config files. Incorrect configurations can open Web sites to application security holes such as session hijacking, Cross-Site Scripting attacks, and even allow the disclosure of private data to attackers. An additional problem is that Web.config files were designed to be changed at any time, even after the Web-based applications are in production.

A well-intentioned system administrator could inadvertently get around application security measures and open the Web site to attack just by modifying the configuration file. And because .NET configuration files operate in a hierarchical manner, a single change to the global Machine.config file could affect every Web site on the entire network.

In fact, attacks upon the Web application layer now exceed those conducted at the network level, and can have consequences which are just as damaging. By "baking in" application security from the start of the development process, rather than trying to ”brush it on” at the end, you are much more likely to create secure applications that will withstand hackers' attacks. However, even the most meticulous and security-aware C# or VB.NET code can still be vulnerable to attack if you neglect to secure the Web.config configuration files of your application. Incorrectly configured Web-based applications can be just as dangerous as those that have been incorrectly coded. To make matters worse, many configuration settings actually default to insecure values.


1. Custom Errors Disabled

When you disable custom errors as shown below, ASP.NET provides a detailed error message to clients by default.

Vulnerable configuration:
<configuration>
<system.web>
<customErrors mode=”Off”>

Secure configuration:
<configuration>
<system.web>
<customErrors mode=”RemoteOnly”>

In itself, knowing the source of an error may not seem like a risk to application security, but
consider this: the more information a hacker can gather about a Web site, the more likely it is that he will be able to successfully attack it.

An error message can be a gold mine of information to an attacker. A default ASP.NET error message lists the specific versions of ASP.NET and the .NET framework which are being used by the Web server, as well as the type of exception that was thrown. Just knowing which Web-based applications are used (in this case ASP.NET) compromises application security by telling the attacker that the server is running a relatively recent version of Microsoft Windows and that Microsoft Internet Information Server (IIS) 6.0 or later is being used as the Web server.

You can build up application security to prevent such information leakage by modifying the mode attribute of the <customErrors> element to On or RemoteOnly. This setting instructs Web-based applications to display a nondescript, generic error message when an unhandled exception is generated.
Another way to circumvent this application security issue is to redirect the user to a new page when errors occur by setting the defaultRedirect attribute of the <customErrors> element.

2. Leaving Tracing Enabled in Web-Based Applications

The trace feature of ASP.NET is one of the most useful tools that you can use to ensure application security by debugging and profiling your Web-based applications. Unfortunately, it is also one of the most useful tools that a hacker can use to attack your Web-based applications if it is left enabled in a production environment.

Vulnerable configuration:
<configuration>
<system.web>
<trace enabled=”true” localOnly=”false”>

Secure configuration:
<configuration>
<system.web>
<trace enabled=”false” localOnly=”true”>

When the <trace> element is enabled for remote users of Web-based applications ( localOnly="false"), any user can view an incredibly detailed list of recent requests to the application simply by browsing to the page trace.axd. If a detailed exception message is like a gold mine to a hacker looking to circumvent application security, a trace log is like Fort Knox! A trace log presents a wealth of information: the .NET and ASP.NET versions that the server is running; a complete trace of all the page methods that the request caused, including their times of execution; the session state and application state keys; the request and response cookies; the complete set of request headers, form variables, and QueryString variables; and finally the complete set of server variables.

A hacker looking for a way around application security would obviously find the form variable
histories useful because these might include email addresses that could be harvested and sold to
spammers, IDs and passwords that could be used to impersonate the user, or credit card and bank account numbers. Even the most innocent-looking piece of data in the trace collection can be dangerous in the wrong hands. For example, the APPL_PHYSICAL_PATH server variable, which contains the physical path of Web-based applications on the server, could help an attacker perform directory traversal attacks against the system.

The best way to prevent a hacker from obtaining trace data from Web-based applications is to disable the trace viewer completely by setting the enabled attribute of the <trace> element to false. If you have to have the trace viewer enabled, either to debug or to profile your application, then be sure to set the localOnly attribute of the <trace> element to true. That allows users to access the trace viewer only from the Web server and disables viewing it from any remote machine, increasing your application security.



3. Debugging Enabled

Web servers often are installed with default configurations that may not be secure. These
insecurities include unnecessary samples and templates, administrative tools, and predictable
locations of utilities used to manage servers. Without appropriate security risk management, this can lead to several types of attacks that allow hackers to gain complete control over the Web server.

Vulnerable configuration:
<configuration>
<system.web>
<compilation debug=”true”>

Secure configuration:
<configuration>
<system.web>
<compilation debug=”false”>

Like the first two application security vulnerabilities described in this list, leaving debugging
enabled is dangerous because you are providing inside information to users who shouldn’t have access to it, and who may use it to attack your Web-based applications. For example, if you have enabled debugging and disabled custom errors in your application, then any error message displayed to a user of your Web-based applications will include not only the server information, a detailed exception message, and a stack trace, but also the actual source code of the page where the error occurred. Unfortunately, this configuration setting isn't the only way that source code might be displayed to the user.

4. Cookies Accessible through Client-Side Script

In Internet Explorer 6.0, Microsoft introduced a new cookie property called HttpOnly. While you can set the property programmatically on a per-cookie basis, you also can set it globally in the site configuration.

Vulnerable configuration:
<configuration>
<system.web>
<httpCookies httpOnlyCookies=”false”>

Secure configuration:
<configuration>
<system.web>
<httpCookies httpOnlyCookies=”true”>

Any cookie marked with this property will be accessible only from server-side code, and not to any client-side scripting code like JavaScript or VBScript. This shielding of cookies from the client helps to protect Web-based applications from Cross-Site Scripting attacks. A hacker initiates a Cross-Site Scripting (also called CSS or XSS) attack by attempting to insert his own script code into the Web page to get around any application security in place. Any page that accepts input from a user and echoes that input back is potentially vulnerable. For example, a login page that prompts for a user name and password and then displays “Welcome back, <username>” on a successful login may be susceptible to an XSS attack.

As mentioned earlier, it is possible to enable HttpOnly programmatically on any individual cookie by setting the HttpOnly property of the HttpCookie object to true. However, it is easier and more reliable to configure the application to automatically enable HttpOnly for all cookies. To do this, set the httpOnlyCookies attribute of the <httpCookies> element to true.



5. Cookieless Session State Enabled

In the initial 1.0 release of ASP.NET, you had no choice about how to transmit the session token
between requests when your Web application needed to maintain session state: it was always stored in a cookie. Unfortunately, this meant that users who would not accept cookies could not use your application. So, in ASP.NET 1.1, Microsoft added support for cookieless session tokens via use of the “cookieless” setting.

Vulnerable configuration:
<configuration>
<system.web>
<sessionState cookieless=”UseUri”>

Secure configuration:
<configuration>
<system.web>
<sessionState cookieless=”UseCookies”>

Web applications configured to use cookieless session state now stored the session token in the page URLs rather than a cookie. For example, the page URL might change from http://myserver.com/MyApplication/default.aspx to
http://myserver.com/MyApplication/(ANCFGNBG12345678)/default.aspx. In this case, 123456789ABCDEFG represents the current user's session token. A different user browsing the site at the same time would receive a completely different session token, resulting in a different URL, such as http://myserver.com/MyApplication/(ABCDFU987678920)/default.aspx.
While adding support for cookieless session state did improve the usability of ASP.NET Web
applications for users who would not accept cookies, it also had the side effect of making those
applications much more vulnerable to session hijacking attacks.

Session hijacking is basically a form of identity theft wherein a hacker impersonates a legitimate
user by stealing his session token. When the session token is transmitted in a cookie, and the request is made on a secure channel (that is, it uses SSL), the token is secure. However, when the session token is included as part of the URL, it is much easier for a hacker to find and steal it. By using a network monitoring tool (also known as a “sniffer”) or by obtaining a recent request log, hijacking the user’s session becomes a simple matter of browsing to the URL containing the stolen unique session token. The Web application has no way of knowing that this new request with session token “123456789ABCDEFG” is not coming from the original, legitimate user. It happily loads the corresponding session state and returns the response back to the hacker, who has now effectively impersonated the user.

The most effective way to prevent these session hijacking attacks is to force your Web application to use cookies to store the session token. This is accomplished by setting the cookieless attribute of the <sessionState> element to UseCookies or false. But what about the users who do not accept cookies?

Do you have to choose between making your application available to all users versus ensuring that it operates securely for all users? A compromise between the two is possible in ASP.NET 2.0. By setting the cookieless attribute to AutoDetect, the application will store the session token in a cookie for users who accept them and in the URL for those who won’t. This means that only the users who use cookieless tokens will still be vulnerable to session hijacking. That's often acceptable, given the alternative—that users who deny cookies wouldn't be able to use the application at all. It is ironic that many users disable cookies because of privacy concerns when doing so can actually make them more prone to attack.


Now we will focus on authentication and authorization application security issues, and detail vulnerabilities commonly found in ASP.NET Web-based applications using Forms authentication. It will also provide some best practices for application security, including locking down your configuration files to ensure that they are not unintentionally modified by well-meaning (but uninformed) programmers or administrators.


6. Cookieless Authentication Enabled

Just as in the “Cookieless Session State Enabled” vulnerability discussed in part one, enabling
cookieless authentication in your Web-based applications can lead to session hijacking and problems with application security.

Vulnerable configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms cookieless=”UseUri”>

Secure configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms cookieless=”UseCookies”>

When a session or authentication token appears in the request URL rather than in a secure cookie, an attacker with a network monitoring tool can get around application security, easily take over that session, and effectively impersonate a legitimate user. However, session hijacking has far more serious consequences for application security after a user has been authenticated.

The best way to prevent session hijacking with Web-based applications is to disable cookieless
authentication and force the use of cookies for storing authentication tokens. This application
security measure is added by changing the cookieless attribute of the <forms> element to the value UseCookies.

7. Failure to Require SSL for Authentication Cookies

Web-based applications use the Secure Sockets Layer (SSL) protocol to encrypt data passed between the Web server and the client. Using SSL for application security means that attackers using network sniffers will not be able to interpret the exchanged data. Rather than seeing plain text requests and responses, they will see only an indecipherable jumble of meaningless characters. You can require the forms authentication cookie from your Web-based applications to use SSL by setting the require SSL attribute of the <forms> element to true.

Vulnerable configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms requireSSL=”false”>

Secure configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms requireSSL=”true”>

The previous section discussed the importance of transmitting the authentication token in a cookie, rather than embedding it in the request URL. However, disabling cookieless authentication is just the first step towards securing the authentication token. Unless requests made to the Web server are encrypted, a network sniffer will still be able to read the authentication token from the request cookie. An attacker would still be able to hijack the user’s session.

At this point, you might be wondering why it is necessary with application security to disable
cookieless authentication, since it is very inconvenient for users who won’t accept cookies, and
seeing as how the request still has to be sent over SSL. The answer is that the request URL is often persisted regardless of whether or not it was sent via SSL. Most major browsers save the complete URL in the browser history cache. If the history cache were to be compromised, the user’s login credentials would be as well. Therefore, to truly secure the authentication token, you must require the authentication token to be stored in a cookie, and use SSL to ensure that the cookie be transmitted securely. By setting the requireSSL attribute of the <forms> element to true, ASP.NET Web-based applications will use a secure connection when transmitting the authentication cookie to the Web server. Note that IIS requires additional configuration steps to support SSL. You can find instructions to configure SSL for IIS on MSDN .

8. Sliding Expiration Used

All authenticated ASP.NET sessions have a timeout interval to protect the application security. The default timeout value is 30 minutes. So, 30 minutes after a user first logs into any of these
Web-based applications, he will automatically be logged out and forced to re-authenticate his
credentials.

Vulnerable configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms slidingExpiration=”true”>

Secure configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms slidingExpiration=”false”>

The slidingExpiration setting is an application security measure used to reduce risk to Web-based applications in case the authentication token is stolen. When set to false, the specified timeout interval becomes a fixed period of time from the initial login, rather than a period of inactivity.

Attackers using a stolen authentication token have, at maximum, only the specified length of time to impersonate the user before the session times out. Because typical attackers of these Web-based applications have only the token, and don't really know the user's credentials, they can't log back in as the legitimate user, so the stolen authentication token is now useless and the application security threat is mitigated. When sliding expiration is enabled, as long as an attacker makes at least one request to the system every 15 minutes (or half of the timeout interval), the session will remain open indefinitely. This gives attackers more opportunities to steal information and cause other mischief in Web-based applications. To avoid this application security issue altogether, you can disable sliding expiration by setting the slidingExpiration attribute of the <forms> element to false.


9. Non-Unique Authentication Cookie Used

A cookie is more than just a value; it is a name-value pair. As strange as it seems, an improperly
chosen cookie name can create an application security vulnerability just as dangerous as an improperly chosen storage location.

Vulnerable configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms name=”.ASPXAUTH”>

Secure configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms name=”{abcd1234…}”>

The default value for the name of the authentication cookie is .ASPXAUTH. If you have only one
Web-based application on your server, then .ASPXAUTH is a perfectly secure choice for the cookie name.
In fact, any choice would be secure. But, when your server runs multiple ASP.NET Web-based
applications, it becomes critical to assign a unique authentication cookie name to each application.
If the names are not unique, then users logging into any of the Web-based applications might
inadvertently gain access to all of them. For example, a user logging into the online shopping site to view his order history might find that he is now able to access the administration application on the same site and change the prices of the items in his shopping cart.

The best way to ensure that all Web-based applications on your server have their own set of authorized users is to change the authentication cookie name to a unique value. Globally Unique Identifiers (GUIDs) are excellent choices for application security since they are guaranteed to be unique.

Microsoft Visual Studio helpfully includes a tool that will automatically generate a GUID for you. You can find this tool in the Tools menu with the command name “Create GUID”. Copy the generated GUID into the name attribute of the <forms> element in the configuration file.

10. Hardcoded Credentials Used

Vulnerable configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms>
<credentials>

</credentials>
</forms>

Secure configuration:
<configuration>
<system.web>
<authentication mode=”Forms”>
<forms>
</forms>

A fundamental difficulty of creating software is that the environment in which the application will be deployed is usually not the same environment in which it is created. In a production environment, the operating system may be different, the hardware on which the application runs may be more or less powerful, and test databases are replaced with live databases. This is an issue for creating Web-based applications that require authentication because developers and administrators often use test credentials to test the application security. This begs the question: Where do the test credentials come from?

For convenience, to avoid forcing developers from spending time on creating a credential store used solely for test purposes (and which would subsequently be discarded when the application went to production), Microsoft added a section to the Web.config file that you can use to quickly add test users to Web-based applications. For each test user, the developer adds an element to the configuration file with the desired user ID and password as shown below:

<authentication mode="Forms">
<forms>
<credentials>
<user name="bob" password="bob"/>
<user name="jane" password="Elvis"/>
</credentials>
</forms>
</authentication>

While undeniably convenient for development purposes, this was never intended for use in a production environment. Storing login credentials in plaintext in a configuration file is simply not secure.
Anyone with read access to the Web.config file could access the authenticated Web application. It is possible to store the SHA-1 or MD5 hash of the password value, rather than storing the password in plaintext. This is somewhat better, but it is still not a secure solution. Using this method, the user name is still not encrypted. First, providing a known user name to a potential attacker makes it easier to perform a brute force attack against the system. Second, there are many reverse-lookup databases of SHA-1 and MD5 hash values available on the Internet. If the password is simple, such as a word found in a dictionary, then it is almost guaranteed to be found in one of these hash dictionaries.

The most secure way to store login credentials is to not store them in the configuration file. Remove the <credentials> element from your Web.config files in production applications.


You’re Not secured Yet

Now that you’ve finished reading the top ten list, and you've checked your configuration settings, your applications are secure forever, right? Not just yet. Web.config files operate in a hierarchical inheritance manner. Every Web.config file inherits values from any Web.config file in a parent
directory. That Web.config file in turn inherits values from any Web.config file in its parent
directory, and so on. All Web.config files on the system inherit from the global configuration file
called Machine.config located in the .NET framework directory. The effect of this is that the runtime behavior of your application can be altered simply by modifying a configuration file in a higher directory.

This can sometimes have unexpected consequences. A system administrator might make a change in a configuration file in response to a problem with a completely separate application, but that change might create a security vulnerability in your application. For example, a user might report that he is not able to access the application without enabling cookies in his browser. The administrator, trying to be helpful, modifies the global configuration file to allow cookieless authentication for all applications.

To keep your application-specific settings from being unexpectedly modified, the solution is to never rely on default setting values. For example, debugging is disabled by default in configuration files.

If you’re examining the configuration file for your application and you notice that the debug
attribute is blank, you might assume that debugging is disabled. But it may or may not be disabled—the applied value depends on the value in parent configuration settings on the system. The safest choice is to always explicitly set security-related values in your application’s configuration.

Ultimately, securing a Web application requires the efforts and diligence of many different groups, from quality assurance to security operations. However, the developer who codes the application itself has an inherent responsibility to instill security into the application from the beginning of the development process. By making security-conscious decisions from the beginning, developers can create applications that users can trust with their confidential information and that are capable of withstanding attacks launched by hackers. Sometimes that process can be as simple as making the right decisions when configuring your application.

million thank to 1 2 for providing these useful security vulnerabilities

Have a secured programming

if this was helpful then please donate as much you want



Cheers

2 comments:

Mahesh Sharma said...

Good post... versy useful... keep on posting such things.
Mahesh Sharma

Anonymous said...

"Sliding Expiration Used" should be left to true! Nothing is more frustrating from the user experience point of view than a session expiring in the middle of a workflow simply because you've used the web application for 30 minutes.

What you should do is use session cookies (ie: cookies that diseappear when you close your browser), or reduce the session timeout. A well-written web application should gracefully ask the user to authenticate again in this case and go back to where the workflow was instead of requesting the user to restart from scratch.