Thursday, January 16, 2014

Windows update crashes ASP.NET web application using EnableEventValidation and EnableViewStateMac

I recently got woken up due to a production web application I am responsible for being down.  Most of the reports indicated the users were not getting .net errors, it simply was not responding to their requests for data.

When I logged onto the site, and navigated to the problem area, I was greated with this error: "A potentially dangerous Request.Form value was detected from the client"; along with the recommendation to disable EnableEventValidation if the error were incorrect.

Bandaid
In an effort to just get the site back up and running I flipped the switch on that page variable.  I'm not sure why the clients never saw the error, but as soon as I flipped that variable I started seeing the same problem that they were reporting; no errors, just no response to requests for data.

Since my development server was functioning perfectly I had to use Response.Write 's on the production server to start tracking down what was going on.  I was shocked to learn that the Page.IsPostBack variable was always returning true.  I got the site functioning again by finding an alternative variable I could use in its place.

With the problem under control efforts were redirected to figuring out what triggered my bad morning.

Problem
My co-worker discovered that windows updates had been applied by our hosting company to our production server.  Through the good old fashioned method of uninstalling until things started working again, he discovered that KB2894842 and KB2894843 were the culprits.  Apparently Microsoft had found a security flaw in pages that had EnableViewStateMac turned off and the fix had resulted in some rather odd results for our site.

EnableViewStateMac was turned off for our site because we were using javascript to submit data from one page to another.  It was necessary to avoid the postback mac validation error "Validation of viewstate MAC failed".  A better option might have been to use strictly .NET controls to handle postback, however it was an old site that originated in classic ASP and the javascript has always worked very well.

Solution
Later versions of .NET now have the ability to post to other pages on the site using the PostBackUrl attribute built into some controls.  I was hoping to capture the javascript generated by such a control and use it to modify my stand alone javascript to enable it to perform a successful post to the next page.

I was disappointed to discover that using the PostBackUrl attribute not only generated additional .NET javascript, but also created a __PREVIOUSPAGE hidden field with a hash value for the next page to validate.  However, I was pleasantly surprised to find out that as long as any control was rendered with that attribute then my original javascript was able to submit the page successfully with no errors.  In fact my site was now able to function with EnableViewStateMac turned on giving me back that additional piece of security.

The compromise I finally settled on was adding a button with a PostBackUrl to my master page and hiding it with CSS.

I am still not sure why the Page.IsPostBack variable stopped functioning correctly and that is part of what prompted this post.  Hopefully if I, or anyone else, runs into a similar problem in the future there will be a place to start looking due to this.