Introduction to ASP.Net Viewstate

Overview

In ASP.NET web applications ViewState has always played a key role. But one thing we should keep in mind that nothing comes free, and ViewState is no exception. But before we dive deep in ViewState let’s have look at how HTTP protocol and ASP.NET life cycle works.

 

HTTP Protocol

As we all know that HTTP is a stateless protocol 🙁 and it uses cookies, sessions to maintain its state. If this is so then question comes into the mind that Where is ViewState in picture?

 

ASP.NET Life cycle

Each time a request arrives at a Web server for an ASP.NET Web page, the first thing the Web server does is hand off the request to the ASP.NET engine. The ASP.NET engine then takes the request through a pipeline composed of numerous stages, which includes verifying file access rights for the ASP.NET Web page, resurrecting the user’s session state, and so on. At the end of the pipeline, a class corresponding to the requested ASP.NET Web page is instantiated and the ProcessRequest() method is invoked (see Figure below).

asp.net-page-lifecycle

ASP.NET Page Life cycle

What is important to realize is that each and every time an ASP.NET Web page is requested it goes through these same life cycle stages (shown in Figure below).

Page Events

Page Events

The Role of ViewState

The main role of viewstate is to persist state across post backs. This poses an another question and i.e.

“What sort of state needs to be persisted?”

To answer this question we have to understand what state doesn’t need to be stored in view state. The property values are something that are automatically assigned to controls on every post backs, so there is no need to store these values in view state.

Then what needs to be stored in view state is any programmatic changes in page’s state.

 

The View State Property

Each control in ASP.NET can store its state, which is accomplished by adding its changed state to its ViewState property. The code would look like this

public string NavigateUrl
{
  get
  {
    string text = (string) ViewState["NavigateUrl"];
    if (text != null)
       return text;
    else
       return string.Empty;
  }
  set
  {
    ViewState["NavigateUrl"] = value;
  }
}

As this code sample illustrates, whenever a control’s property is read, the control’s ViewState is consulted. If there is not an entry in the ViewState, then the default value for the property is returned. When the property is assigned, the assigned value is written directly to the ViewState.

 

Storing Information in Page’s ViewStateProperty

We can use this property to persist page-specific and user-specific information across post backs. From an ASP.NET Web page’s code-behind class, the syntax to use is simply:

ViewState[keyName] = value

There are a number of scenarios when being able to store information in the Page‘s ViewState is useful. The canonical example is in creating a pageable, sortable DataGrid (or a sortable, editable DataGrid), since the sort expression must be persisted across postbacks. That is, if the DataGrid’s data is first sorted, and then paged, when binding the next page of data to the DataGrid it is important that you get the next page of the data when it is sorted by the user’s specified sort expression. The sort expression therefore needs to be persisted in some manner. There are assorted techniques, but the simplest, in my opinion, is to store the sort expression in the Page‘s ViewState.

 

The Cost of View State

Nothing comes for free, and view state is no exception. It imposes two performance hits for every request

  • In save view state control hierarchy is saved in base-64 encoded string which is emitted in “__VIEWSTATE” hidden form field and in load view state the same is decoded and control hierarchy is updated
  • Extra size to the Web page. Some times for view state-heavy pages can be tens of kilobytes 🙁

 

Enabling/Disabling ViewState

The EnableViewState property is defined in the System.Web.UI.Control class, so all server controls have this property, including the Page class.

At control level
<asp:LabelEnableViewState=“false”…></asp:Label>
At individual page level
<%@Page EnableViewState=”False” %>
Page.EnableViewState = false;
At site/application level (in web.config)
<pages enableViewState=”true”>

 

Now, as we know how ASP.NET page and view state works, let’s see what are its security concerns.

 

View State and Security Implications

The view state for an ASP.NET Web page is stored, by default, as a base-64 encoded string. This string can easily be decoded and parsed, displaying the contents of the view state for all to see. This raises two security-related concerns:

  1. Since the view state can be parsed, what’s to stop someone from changing the values, re-serializing it, and using the modified view state?
  2. Since the view state can be parsed, does that mean I can’t place any sensitive information in the view state (such as passwords, connection strings, etc.)?

Fortunately, the LosFormatter class has capabilities to address both of these concerns. Before we delve into the solutions for these concerns, it is important to first note that view state should only be used to store non-sensitive data. View state does not house code, and should definitely not be used to place sensitive information like connection strings or passwords.

There are three ways in which one can stop the modification of View State

  1. Tamper proofing
  2. Encryption
  3. The ViewStateUserKey Property

 

Tamper proofing

A hashcode will not secure the actual data within the ViewState field, but it will greatly reduce the likelihood of someone tampering with ViewState to try to spoof your application, that is, posting back values that your application would normally prevent a user from inputting.

You can instruct ASP.NET to append a hashcode to the ViewState field by setting the EnableViewStateMAC attribute:

<%@Page EnableViewStateMAC=”true” %>

EnableViewStateMAC can be set at the page or application level. Upon postback, ASP.NET will generate a hashcode for the ViewState data and compare it to the hashcode store in the posted value. If they don’t match, the ViewState data will be discarded and the controls will revert to their original settings.

By default, ASP.NET generates the ViewState hashcode using the SHA1 algorithm. Alternatively, you can select the MD5 algorithm by setting <machineKey> in the machine.config file as follows:

<machineKey validation=”MD5″ />

 

Encryption

Ideally the view state should not need to be encrypted, as it should never contain sensitive information. If needed, however, the LosFormatter does provide limited encryption support. The LosFormatter only allows for a single type of encryption: Triple DES. To indicate that the view state should be encrypted, set the <machineKey> element’s validation attribute in the machine.config file to 3DES.

In addition to the validation attribute, the <machineKey> element contains validationKey and decryptionKey attributes, as well. The validationKey attribute specifies the key used for the MAC; decryptionKey indicates the key used in the Triple DES encryption. By default, these attributes are set to the value “AutoGenerate,IsolateApp,” which uniquely autogenerates the keys for each Web application on the server.

 

Concerns with Encryption

This setting works well for a single Web server environment, but if you have a Web farm, it’s vital that all Web servers use the same keys for MAC and/or encryption and decryption. In this case you’ll need to manually enter a shared key among the servers in the Web farm. For more information on this process, and the <machineKey> element in general, refer to the <machineKey> technical documentation and Susan Warren’s article Taking a Bite Out of ASP.NET ViewState.

 

The ViewStateUserKeyProperty

This property, if used, must be assigned a string value in the initialization stage of the page life cycle (in the Page_Init event handler). The point of the property is to assign some user-specific key to the view state, such as a username. But if we use usernames to assign some key to view state then it is very much guessable. Recommended value is SessionID. Code would look like this

Page.ViewStateUserKey = Session.SessionID;

The following figure illustrates that how we can prevent view state manipulation using ViewStateUserKey

ViewStateUserKey

ViewStateUserKey

 

Conclusion

In this article we examined the ASP.NET view state, studying not only its purpose, but also its functionality. To best understand how view state works, it is important to have a firm grasp on the ASP.NET page life cycle, which includes stages for loading and saving the view state.

This article wrapped up with a look at security concerns with view state. By default, the view state performs a MAC to ensure that the view state hasn’t been tampered with between postbacks. ASP.NET provides the ViewStateUserKey property to add an additional level of security. The view state’s data can be encrypted using the Triple DES encryption algorithm, as well.

 

Reference

To read more about ASP.NET View State you can use this link

http://msdn.microsoft.com/en-us/library/ms972976.aspx

Posted in ASP.NET, Programming Language, Secure .NET Coding, Security