Securing your ViewState 2: ViewStateUserKey and custom ViewState persister

In part 1 of this post, you can see how you can encrypted your ViewState and ensure its integrity across postbacks. A few more things you can do to beef up your ViewState security.

ViewState validation with ViewStateUserKey

It is possible for someone who got a hand on your ViewState data and reuse it at some other time or different user session. This scenario is what we call ‘One-Click attacks‘, a variation of XSS. ASP.NET provides ViewStateUserKey as a way to ensure that ViewState data is tied to specific user session.

In short, ASP.NET can use ViewStateUserKey for encryption salt. So if we set ViewStateUserKey to current session ID or specific user information, this ViewState data will not be usable to other users or sessions. For more detail explanation, check out Scott Hanselman’s posts here and here.

Setting ViewStateUserKey

Note that setting ViewStateUserKey should be called early in the OnInit method, before ViewState is encrypted.

 

Taking ViewState out of Page output

The ultimate measure to secure ViewState is to remove it from rendered page altogether and store it somewhere else. Apart from tighten up security, another benefit is reducing the size of output HTML page.

 

ASP.NET uses a page state persister class to take care of persisting ViewState data. By default, ASP.NET page uses HiddenFieldPageStatePersister, which as the name implies, persist ViewState to page’s hidden field. Another default persister is SessionPageStatePersister which keeps page ViewState in current session.

To switch to use session persister, add <sessionPageState> in Web.config file. You can also specify the size of maximum saved ViewState.

Configure SessionPageStatePersister in Web.Config file

 

Custom page ViewState Persister

ASP.NET 2.0 allows you to create custom persister by overriding PageStatePersister class. In the code sample, I create a persister that save ViewState in a separate text file.

Creating custom page viewstate persister
Subclassing System.Web.UI.PageStatePersister

Next, we have to override Save method. This method is called when ViewState data is persisted to storage medium. In this case, I persist ViewState data to Text file.

Override Save method
Generate GUID for ViewState persisting file name

Note that I keep GUID in a hidden field. We’ll need this GUID when we load back ViewState on postback.

Persist ViewState data to text file
Writing ViewState data to text file.

 

You’ll see on the output HTML that __VIEWSTATE hidden field is now empty! We only keep GUID in a hidden field to refer back when we load ViewState data. This helps reduce page size significantly if your page relies on heavy ViewState data.

 

Lastly, override Load method to get ViewState value back from persistence medium.

Loading ViewState data back

Now you need to tell your aspx page to use this custom persister. To do that, simply override PageStatePersister property on the page.

Override PageStatePersister property

You can download the code for this class HERE.

Where should I put ViewState data

Putting ViewState in Session has some disadvantages. First, you can lose session ViewState if it reaches historySize limit (if you open multiple windows of the same web page). You may also run into a memory problem if ViewState is very large. Consider when you have a lot of users with large ViewState data, all these data is kept in web server memory. From the sample code, persisting ViewState to external text file is effective against large ViewState, yet it can incur significant file IO cost. With ability to create custom page ViewState persister, you can go as far as persist it to SQL database :)

Teera on June 29th 2008 in ASP.NET, Software Development, Web Dev, .NET

Trackback URI | Comments RSS

Leave a Reply