Archive for the 'ASP.NET' Category

Client-side IsPostback checking

I ran into a situation that I have to write JavaScript that execute only when the page is posted back. Currently there’s no straight forward way in ASP.NET Ajax to check IsPostback from JavaScript. If you google around, you might find various way of getting this to work, like this one.

After some thought, the easiest hack I came up with is this.

function IsPostBack() {
   return <%= IsPostBack.ToString().ToLower() %>;
}

:)

No Comments »

Teera on July 18th 2008 in ASP.NET, Software Development, Web Dev, .NET

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 :)

No Comments »

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

Securing your ViewState 1: ViewState encryption

I didn’t pay much attention on the security aspect of ASP.NET ViewState until a few days ago when I got to use my friend’s labtop. After browsing around, I could see that his web browsers cached some pages from ASP.NET website. So just for fun, I quickly downloaded ViewStateDecoder and decoded the cached page’s leftover ViewState. Here’s what I found:

Using ViewStateDecoder to look at page's ViewState
The blackened part is my friend’s email

Now this cached page was from an online shopping site in Asia. With information like username and email, a moderately evil geek can do quite a lot of financial damage to my poor friend.

As ASP.NET developer, ViewState is one thing that we grow to love and hate. Love - it’s the key technique that make stateful ASP.NET controls work on stateless HTTP protocol! Hate - it’s heavyweight and expose a security hole. Here’re a few things you can do to protect ViewState from malicious attacker.

ViewState as hidden field

 

Enable ViewState MAC

MAC - Machine Authentication Check, is a mechanism to ensure the integrity of ViewState data (data received is the same as data transmitted). Before ViewState data is sent out, ASP.NET quickly computes hash data from the ViewState and append that hash to the end of ViewState. When Postback occurs, ASP.NET deserialized returning ViewState and compare the original hash value to the returned hash value. If both values are NOT the same, the ViewState data has been corrupted/changed.

Enabling ViewState MAC is very easy. You can either do it for a specific page.

Enabling ViewStateMac for aspx page

Or you can apply to every pages through Web.config file

Enabling ViewStateMac in Web.config

By default, MAC hashing algorithm is SHA1. You can change the algorithm by setting validation attribute of machineKey section in Web.config file.

MachineKey validation alrorithm for MAC
You can also encrypt it by selecting Triple DES (3DES) algorithm

 

ViewState Encryption

If you select “3DES” or “AES” as machineKey validation attribute, your ViewState will get encryption automatically. Specifying encryption algorithm in Web.Config file will apply to all pages. You can enable/disable encryption on page basis as well by setting ViewStateEncryptionMode. By default, the value is Auto.

Enabling ViewState page encryption

An extra hidden field will be added for a page with encrypted ViewState. This marker field tells ASP.NET that the ViewState hidden field has to be decrypted on postbacks.

VIEWSTATEENCRYPTED extra field

Alternatively, you can programatically request ViewState encryption from C# code. The case that you’ll need this is when you have ViewStateEncryptionMode directive set to ‘Auto’ and want to request encryption for this page from code. ASP.NET 2.0 introduced a new Page.RegisterRequiresViewStateEncryption() method. Note that you should call this method before LoadViewState event for postback (call it in Init method).

Page.RegisterRequiresViewStateEncryption method

By default, ASP.NET generate random key for encryption. If you want a stronger encryption or you are working in a web farm, you’ll need to specify your own validation key. The validation key is a string of 20 to 64 random, cryptographically-strong bytes, represented as 40 to 128 hexadecimal characters. The longer the key the better.

The easiest way to generate this key is to use System.Security.Cryptography.RNGCryptoServiceProvider class.

Generate cryptographically strong validation key
The keyLength parameter can be 40 or 128. This method returns cryptographically strong validation key.

Once you get the validation key, set it for machineKey in web.config file. If your application is hosted in a web farm, make sure that the validation key is consistent across all the servers.

Setting validation key in Web.config

In the part 2 of this post, I’ll show you how to user ViewStateUserKey and create custom ViewState persister that allows you to remove ViewState data from rendered page entirely.

 

 

1 Comment »

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

Building multi-language ASP.NET site with resource localization

Last year I added additional Thai and Japanese languages to my spa website. Now that I recently got a chance to do the same for a Java and PHP web sites, I’m amazed at how easy it is to do this in ASP.NET.

Adding multiple languages to ASP.NET site with resources localization 1

To do this, I first start from designing the web page. I create a language bar user control that contain 3 link buttons for each language. I put this user control at the bottom of the page.

Now in my web project in Visual Studio, I add resource files to the project. If you are using VS2005 or 2008, the tool will automatically add App_GlobalResources folder for you. Here I create 3 resource files for 3 languages. Note that I name them all the same (I put the localized strings for entire site in one file). You can have multiple resource files as well. I also append “.<culture code>” to the end of each resource file to indicate the language that it should serve.

Adding multiple languages to ASP.NET site with Resources localization 2

I go ahead and design the web page. For each text label, instead of define the string content for Text property, I set it so that the value would be automatically injected from the resource file. The value format is

<%$ Resources:<resource file name>, <resource entry name> %>

Adding multiple languages to ASP.NET site with Resources localization 4

Alternatively, I can programmatically set the localized string value from C# code as well. Here’s a code-behind example.

Adding multiple languages to ASP.NET site with Resources localization 5

After I have all the required labels laid out, I can now go to the resource file and enter the localized string values. Note that HTML tag is also allowed for localized string value.

Adding multiple languages to ASP.NET site with Resources localization 3

Lastly, the most important piece. How you can go about telling ASP.NET of the language you choose. The key here is to set the right UICulture for the current thread. The way I do this is to keep the current culture code in a session value. Once the user selects preferred language from the user control, I assigned the value to the current thread.

Adding multiple languages to ASP.NET site with Resources localization 6
Using the selected language’s culture info code to create CultureInfo object and assign it to the current thread.

You also have another option by setting your web page to automatically localize display string by the browser’s current culture. Simply set aspx page Culture attribute to “auto” and the ASP.NET runtime will use browser’s current culture setting by default.

Adding multiple languages to ASP.NET site with Resources localization 7

And that’s it. I didn’t realize how easy it was until I had to do this same thing on other platform.

No Comments »

Teera on April 6th 2008 in ASP.NET, Software Development, Web Dev, .NET