This is a story of me and my friend fixing a problem occurred in one of my ASP.NET web applications. It happened last year. One day, when he browsed my new web app, he realized that there was a very strange server error. It said “validation of viewstate MAC failed”, as shown in the following screenshot.
When he showed me this error, I was like what the hash is going on. I spotted the words “Web Farm” and “cluster”. However, I’m not using any web farm and cluster. Also, what is “viewstate MAC”?
Viewstate and MAC
What is Viewstate?
According to MSDN, Viewstate is a mean to store information directly in the web page so that the page and control will not be lost with each round trip. This is because a Web application is states and thus a new instance of the Web page class will be created each time the page is requested from the server. So, Viewstate can be used to store values that have to be retained during postback, for example the value entered by the user into a textbox on the web page.
By default, Viewstate data is stored in a hidden field on the web page. However, it is very easy for a malicious user to get access to the contents of a hidden field and modify it. Thus, there is a need to secure our Viewstate data. The way it’s done is through creating a hash value of the Viewstate data with MAC (Machine Authentication Code) key and using the hash to check whether the data has been corrupted or not.
Okai, now I sort of knowing what Viewstate is and why MAC is mentioned in the error message.
The next step will be finding the solution to this problem. You should be able to find a list of articles and forum threads discussing about this problem on Google.
The first article I found is a blog post “Validation of viewstate MAC failed error” on MSDN. One of the workarounds suggested is setting enableEventValidation to false and viewStateEncryptionMode to Never. This method is basically just throwing away the viewstate validation and opening a hole in the security of the web app. If I use this method in my work, I guess I will be beaten by my manager.
The second workaround mentioned in the article can only work if the problem happens because the postback occurs before the EventValidation field has been rendered. This is no longer an issue in the modern ASP web app. The third and fourth workarounds are also just re-ordering the position of the hidden field storing Viewstate data to the beginning of the form to prevent postback happens before the hidden field is rendered. So, they do not really help.
For my case, the problem is most probably caused by the browser caching. My friend’s browser was using the cached version of the web pages. However, expecting the users to clear their cache and cookies is totally not acceptable. So, the solution I chose is adding a machine key to web.config. There are also online tutorials on how to do that, for example an article written by Adam in 2009, “How To Fix the: “Validation of viewstate MAC failed” Error (ASP.NET MVC)“. The online tool that I use to generate a random machine key is http://aspnetresources.com/tools/machineKey (EDIT on 11 Dec 2014: This link is reported to be dead by one of our readers, Naveen, in the comment section below. You can now try https://www.insitesystems.com/services/tools/machine-key-generator.html).
<configuration> ... <system.web> ... <machineKey validationKey="..." decryptionKey="..." validation="SHA1" decryption="AES" /> ...
Yup, so that is basically how I solved it until someone hacks my server and gets to know the value of my machine key. =P
p/s: My friend was staying at Hong Kong and thus I named this problem the “Hong Kong Friend’s Problem”.