Avoid Session hijacking, session fixation in ASP.NET

Post date: Jul 29, 2011 3:07:06 AM

ASP.NET greatly simplifies the process of managing both session and authentication tokens. A developer can use the default ASP.NET session management features or expand on those to provide more robust and secure token management features. In this section, we will cover:

Designing a Secure Token

Summary:

Threats:

To be secure, a token must meet certain criteria

Session hijacking, account hijacking, session fixation, information leakage

Web developers have long used session and authentication tokens in their Web applications. However, lack of understanding of session management has led to the compromise of many Web applications. It is important to keep session tokens secure, but it’s even more important to keep authentication tokens secure. For an authentication token to be secure, it should pass a number of tests, as outlined in the following sections.

Is the Token Tightly Bound to the User’s Session?

This is the most common failure of tokens, often allowing attackers to hijack another user’s session by manipulating a token. Most token schemes have no binding to a particular user, relying on the assumption that possession of the token is proof of ownership.

Does the Server Transmit the Token to the Client in a Secure Manner?

Essentially, this means using SSL or IPSec to encrypt the traffic when sending the token. If the traffic is not encrypted, the token could be visible to others. When you use a cookie, it is important to mark it as secure so that the client’s browser handles it properly.

Does the Application Use a Sufficiently Large Keyspace?

To prevent brute-force attacks on the session token, you should use a large enough token to ensure that an attacker cannot easily come across a valid token. For example, a 128-bit number allows for 340,282,366,920,938,463,463,374,607,431,768,211,456 (or 2128) possible unique session tokens.

Does the Application Use a Strong Random-Number Generator for Tokens?

A strong random-number generator ensures that a token utilizes the available keyspace and does so in an unpredictable manner. It is impossible for a computer to generate a truly random number, but many pseudo-random-number generators are good enough that you cannot easily reproduce the same results twice.

Does the Application Create New tokens for Each Login?

A user should never be allowed to reinstate a session with an old token. Each time the user authenticates, always destroy any old tokens and initiate a new session with a new token.

Will the System Accept Any Token Provided by the Client?

If a system accepts a client-provided token, it could be vulnerable to what is called a session fixation attack. With this kind of attack, the attacker sends the victim a URL that contains a session token. The victim clicks the URL and enters his or her login credentials, validating the session. The attacker then browses to the site using that same session ID and gains access to the user’s account. Not only should you reject such tokens, you should also log them as a security incident.

Is It Possible for a User to Manipulate the Token to Hop to Another Account?

Many Web applications use a weak session token that, when modified, allows an attacker to hop to another authenticated user’s account. The token should always be bound to a specific account and session, and you should always avoid sequential or predictable session tokens.

Can the Application Detect a Modified or Invalid Token?

To prevent others from modifying a token to somehow exploit an application, the system should be able to identify a cookie that has been changed from its original state. The application should always be able to identify a token that it did not issue itself or that a user has changed since issuing by using a digital signature or hash of the token.

Does the Token Uniquely Identify the Client?

The token should always be a random number that in no way identifies the client. The token should be a random number generated by the server and stored on the server side in association with the user ID. When the client provides the token to the server, the server looks up that session and identifies the client.

Does the Token Properly Limit Its Scope?

An application should associate a token only within a limited application scope to prevent users from overstepping their bounds or from inadvertently transmitting their tokens across an insecure connection. This is especially important for cookies so that the cookie is not sent when moving from a secure to an insecure page. It also prevents cookie-hijacking attacks from servers with the same domain name.

Does the Token Have Both Relative and Absolute Timeouts?

A session token should be valid for only a short period of time since the user’s last request. Because it is possible for a user to keep a token alive indefinitely, tokens should also have an absolute expiration. At this point, all information regarding this token should be destroyed and a new token issued if the session is still active.

Does the Client Store the Token After the Session Ends?

This is a problem because the user may be connecting from a shared computer. The client’s browser stores persistent cookies, keeps a history of URLs, and caches visited pages, making this a challenge for all types of tokens.

Does the User Have the Option to Terminate a Session?

Although a session should eventually time out, users should also have the option to terminate sessions themselves. When they do so, all information regarding the token should be destroyed. It is also important that you delete any old sessions from that user who may remain in the database.

Can You Revoke a Token from the Server?

Sometimes you need to revoke a single session or even all sessions due to a security incident. The token must rely on the server for its validity. For example, with the built-in ASP.NET session tokens, the server can only determine if it issued the token based on its hash, but because the server does not maintain a list of sessions, there is no mechanism to revoke a token.

Unfortunately, few token schemes meet all these criteria and in fact, the HTTP protocol itself makes it difficult to meet all these perfectly. Every token method has its weaknesses and no single method is perfect. Moreover, many developers trade security for greater compatibility with their wide range of customers.

Security Policies

Selecting a Token Mechanism

Summary:

Threats:

Carefully choose a token mechanism that provides users with the best security

Session hijacking, account hijacking, session fixation, information leakage

URL-Based Tokens

URL-based tokens are tokens that exist on the URL as part of the URI path or as part of the query string, as shown in these examples:

http://www.example.com/inbox.aspx?sessionID=6861636B696E67746865636F6465 http://www.example.org/user.aspx?sid={6861-636B-696E-6774-6865-636F-6465} http://www.example.net/(o5lmpx45ylxps255o3bxzoib)/Default.aspx

This method is perhaps the most common because it is the most universally compatible. The drawback with this method is that it is easy for others to discover your session token. The token may appear in your browser history, your browser cache, or logs of any intermediary proxy servers or filters and can be sniffed by others, provided that it is not secured via SSL, and it will show up as the referrer when you click links to other sites. One old trick that used to work with many free Web-based e-mail systems is to embed an image link that you control in an e-mail and wait for the person to view the message. Once they do, their session token will appear in your Web logs under the referer[sic] field. All you have to do is enter that URL and you have access to that person’s account.

If you use URL-based tokens, there is also the risk of users sharing, copying, or bookmarking URLs that contain session tokens. Another problem with URL-based tokens is that they are more susceptible to session fixation attacks because it is easier for an attacker to send you a URL that already contains a session token. (Session fixation attacks are explained in more detail later in this chapter.)

Cookie-Based Tokens

Another common method for communicating tokens is using an HTTP cookie mechanism. Most browsers support cookies, but some users block them for privacy reasons or in the belief that they are a security risk. But an increasing number of Web sites require the use of cookies to authenticate to their sites. The argument of privacy is weak because users are already identifying themselves with their credentials.

Cookies are somewhat more secure than other methods because:

However, cookies do not guarantee immunity from session-hijacking attacks. If not sent over an SSL connection, cookies are still vulnerable to sniffing and man-in-the-middle attacks, and the attacker may be able to physically steal the cookie if he has access to the user’s computer. Microsoft introduced an HttpOnly cookie in Internet Explorer 6 Service Pack 1 that stops one specific type of cookie-hijacking attack but does not completely eliminate the problem. Most security problems related to cookies are due to poor security policy and development practices. Later in this chapter, we look at how to properly configure and use cookies for authentication tokens.

ASP.NET forms authentication uses cookie-based tokens, but it also offers the option to use encryption and verification of the session token.

Form-Based Tokens

Some Web sites embed tokens as hidden fields within HTML forms. The browser submits the session token in the request body when moving to a new page. Here is an example of using a token in a hidden form field:

<INPUT TYPE="hidden" NAME="sessionID " VALUE="6861636B696E67746865636F6465">

The security of hidden form fields is about the same as cookies, but it does not provide as many features as cookies. Normally this method works best for limited authentication state management, such as using a shopping cart.

ASP.NET provides a form-based mechanism called ViewState that enhances the hidden form field technique to include encryption and a more structured storage. ViewState overcomes some of the problems of form-based tokens, but it still is not a perfect solution. We look at ViewState and some techniques for making it more secure later in this chapter.

The basic obstacle here is that none of these state management techniques was designed for secure token management, nor are they entirely appropriate for that use by themselves. None of these methods provides the robust security and privacy features required for sensitive Web-based applications. To make matters worse, although SSL can compensate for many of these limitations, many large Web sites still fail to use it, and it is very rare to see a Web site utilizing client-side certificates.

Security Policies

Using State Providers

Summary:

Threats:

Properly secure the state provider you select

Session hijacking, account hijacking, session fixation, information leakage

ASP.NET supports three methods for storing session state on the server: in-process, ASP.NET State Service, or SQL Server. The decision to use one method over the other is based on reliability and scalability requirements. In-process state management is similar to what was available with IIS 5 and classic ASP. In-process state management is handled locally within the ASP.NET worker process. It is the fastest of the three, but all session information is lost if IIS or the Web application restarts. The ASP.NET State Service is an external service that maintains state even if IIS restarts, and it can be shared by multiple servers. You can run the ASP.NET State Service locally or on a remote computer. SQL Server state management is the most scalable and reliable solution but the slowest and most difficult to configure.

Securing In-Process State

There is not much to do to customize local state management, but there are a few steps you should take if you are using it. To use in-process state management, edit your web.config file as follows:

<sessionState    mode="InProc"   cookieless="false"    timeout="15"  />

If you use in-process state management, be sure to disable the ASP.NET State Service using the Services administrative tool. If you have Windows Server 2003, you can also disable it using this command from a command prompt:

C:\>sc config aspnet_state start= disabled

Securing the ASP.NET State Service

The ASP.NET State Service is essentially a miniature HTTP server that specifically handles session state PUTs and GETs. Figure 3.1 shows a packet capture of the type of traffic ASP.NET sends to the service.

***AP*** Seq: 0xE6F3358D  Ack: 0x85F6237  Win: 0x4470  TcpLen: 20 0x0000: 00 D0 B7 8F 6A F0 00 A0 24 E6 4C 8E 08 00 45 00  ....j...$.L...E. 0x0010: 00 ED 0A 66 40 00 80 06 DA 97 0A 55 00 63 0A 55  ...f@......U.c.U 0x0020: 00 01 08 72 00 50 E6 F3 35 8D 08 5F 62 37 50 18  ...r.P..5.._b7P. 0x0030: 44 70 CA E1 00 00 50 55 54 20 2F 2F 4C 4D 2F 57  Dp....PUT //LM/W 0x0040: 33 53 56 43 2F 31 2F 52 6F 6F 74 2F 73 74 61 74  3SVC/1/Root/stat 0x0050: 65 2F 46 6F 72 6D 73 28 52 79 6A 6B 41 63 46 59  e/Forms(RyjkAcFY 0x0060: 58 42 70 37 2B 4D 52 78 45 64 70 68 78 64 6E 41  XBp7+MRxEdphxdnA 0x0070: 50 36 63 3D 29 2F 74 76 6C 64 77 74 79 33 79 34  P6c=)/tvldwty3y4 0x0080: 64 79 76 6E 6E 61 32 6E 73 33 76 32 35 35 20 48  dyvnna2ns3v255 H 0x0090: 54 54 50 2F 31 2E 31 0D 0A 48 6F 73 74 3A 20 31  TTP/1.1..Host: 1 0x00A0: 30 2E 38 35 2E 30 2E 31 0D 0A 54 69 6D 65 6F 75  0.85.0.1..Timeou 0x00B0: 74 3A 32 30 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65  t:20..Content-Le 0x00C0: 6E 67 74 68 3A 33 34 0D 0A 4C 6F 63 6B 43 6F 6F  ngth:34..LockCoo 0x00D0: 6B 69 65 3A 30 0D 0A 0D 0A 14 00 00 00 00 01 00  kie:0........... 0x00E0: 01 00 00 00 FF FF FF FF 08 54 65 73 74 49 74 65  .........TestIte 0x00F0: 6D 01 07 57 6F 6F 68 6F 6F 6F FF                 m..Woohooo. 

Figure 3.1: ASP.NET State Service Packet Capture

The weakness with the ASP.NET State Service is that it uses an unencrypted and unauthenticated connection to the Web server or with anyone else who can reach the open port. Unfortunately, the service has only a limited facility to restrict IP addresses. In fact, all it can do is allow or block all external connections through an undocumented registry setting. This works well if you use the ASP.NET State Service on only one computer, but it will not work in a Web farm. If you run the service for a single local Web server, you can set that key as follows:

To effectively limit access to this service, you must configure an external packet filter or use IPSec rules to restrict (and encrypt) traffic to authorized servers only. Note that you can also use an obscure port for the service to make it more difficult to locate. You can do this with the following registry setting:

Tip 

Note that if you change the default listening port, be sure to make the same change in your web.config file.

To configure ASP.NET to use the state service, set the following in your web.config file:

<sessionState    mode="StateServer"   stateConnectionString="tcpip=10.185.0.31:3104"   cookieless="false"    timeout="15"  />

If you want to further obscure the location and port of the state service, you can encrypt the connection string and save it in the registry with the aspnet_setreg.exe (available at http://support.microsoft.com/_default.aspx?scid=329290). To use this tool, enter a command such as this:

C:\>aspnet_setreg -k:Software\YourApp\State  _-d:stateConnectionString="tcpip=10.185.0.31:3104"

After that, change the stateConnectionString attribute in your web.config file _to this:

stateConnectionString  ="registry:HKEY_LOCAL_MACHINE\SOFTWARE\YourApp\ State\ASPNET_SETREG,_stateConnectionString"

Securing SQL Server State Management

To use SQL Server to manage session state, set your web.config file as follows:

<sessionState    mode="StateServer"   sqlConnectionString="data source=10.185.10.4;Trusted_Connection=yes"   cookieless="false"   timeout="15"  />

You must also configure SQL Server with the appropriate tables to save session state. For more information on how to do this, see http://support.microsoft.com/?scid=317604.

After configuring the SQL Server tables, create a new low-privilege account on the database server dedicated to state management. As with the state service configuration, you can use aspnet_setreg.exe to encrypt your database connection string:

C:\>aspnet_setreg -k:Software\YourApp\State  -d: sqlConnectionString="data source=10.185.10.4;Trusted_Connection=yes"

After that, change the sqlConnectionString attribute in your web.config file _to this:

sqlConnectionString="registry:HKEY_LOCAL_MACHINE\SOFTWARE\YourApp\State\ ASPNET_SETREG, sqlConnectionString"

General Settings

The cookieless option tells ASP.NET to add the session token to the URL, rather than using a session cookie. Some flaws with the ASP.NET session tokens might make them inappropriate to use on the URL. ASP.NET will accept any syntactically valid token and therefore is vulnerable to session fixation. It also provides no encryption or hashing to ensure the token originated from the server and that no one has modified it. Cookie-based tokens have the same problems, but they are somewhat easier to control. For session state, ASP.NET uses a session cookie, so the browser should not save this cookie to disk.

The timeout value is the number of minutes to keep the session alive. Keep this number as low as is practical for your application to reduce exposure to session-hijacking attacks.

Security Policies