As is becoming the norm, changes to ASP.NET and .NET have been coming fast and furious, accelerating with the BUILD conference last April, and continuing with last month’s TechEd tech-fest. However, one significant security change has largely been drowned out in the noise of other changes. It’s a breaking change that affects the EnableViewStateMac configuration setting in ASP.NET Web Forms applications.
Just to remind you, the EnableViewStateMac setting determines whether ASP.NET checks the message authentication code (MAC) in a page’s view state. Each time the server generates view state for a page sent to the client, ASP.NET generates a MAC that assures the authenticity and integrity of view state, ensuring that what was sent to the client isn't different from what's sent back to the server on the next page posting. If you want more details about EnableViewStateMac, check out Troy Hunt’s "Understanding (and testing for) view state MAC in ASP.NET web forms" blog post from September, 2013.
Developers have long been able to control the use of the view state MAC using the EnableViewStateMac attribute of either the Web Forms Page directive for a single page:
- <%@ Page EnableViewStateMac="true" ... %>
or across the application using the pages element in web.config:
- <pages enableViewStateMac="true">
In the directives, 'true' means that the MAC is checked when the server receives view state from the client, and is the default. You’d have to explicitly set the directive to 'false' to turn off the protection that view state MAC affords for ensuring that view state wasn’t tampered with in any way.
For a long time, the recommendation has been to never disable the view state MAC in a production environment; doing so makes abusing view state far too easy, even if you’re not using view state. Of course, there are some tempting scenarios where disabling the view state MAC seems like the only option, particularly when page requests are handled by different servers. Over time however, developers have found better, more secure workarounds that usually don’t involve virtually handing the keys to the kingdom over to attackers. In essence, turning off view state MAC is turning off the strong, built-in protections ASP.NET provides for the view state. Hopefully, a fundamental distrust of all user input is well ingrained in every web developer’s psyche at this point.
In hindsight, Microsoft shouldn't have provided an option to disable view state MAC in the first place. I vaguely recollect from the earliest days of ASP.NET that disabling view state MAC was the only solution to some problems, but those problems have long since been resolved in better, more secure ways.
So in May 2014, Microsoft made it official: In ASP.NET 4.5.2, applications act as though EnableViewStateMAC is set to true, regardless of what you set it to at any scope. In fact, the ASP.NET 4.5.2 and EnableViewStateMac blog post in Microsoft’s .NET Web Development and Tools Blog that announced the change was unusually blunt:
Starting with ASP.NET 4.5.2, the runtime enforces EnableViewStateMac=true.
If an application sets <%@ Page EnableViewStateMac="false" %> as a directive or <pages enableViewStateMac="false" /> as a config setting, the runtime ignores it and pretends that the developer had written "true" instead.
I particularly like the wording—that the runtime "pretends" that the developer had done the correct thing instead of the boneheaded thing that Microsoft allowed by providing the option in the first place.
Part of me—the hard-core, control freak developer side—is appalled by Microsoft's change. First, provide a setting, and then deliberately ignore it? How dare they pretend that I had done something different, as wrong as that I might be?
But the fact of the matter is that view state MAC really should never be disabled. It may take a little extra work to sync machine keys when using a Web farm or to handle various other scenarios, but that extra work is well worth a far more secure site. This is particularly important in this day and age when attackers are getting ever more clever at exploiting application flaws in unexpected ways.
So you'll need to be aware when you move an application to ASP.NET 4.5.2; your code may break if you rely on disabling view state MAC, and you'll need to fix it and do things securely. The ASP.NET 4.5.2 and EnableViewStateMac blog post contains helpful information about resolving view state MAC problems. Once you've fixed these problems, then you can sleep better at night, knowing that you’ve shut down a whole class of attacks.
Dare I say it? Thanks, Microsoft! But what took you so long?