Security for Microsoft is a double-edged sword. As business needs become increasingly complex, Microsoft has to make sure that its products and platforms are inherently secure, without absolving developers and systems administrators of their ultimate responsibility for ensuring security at the implementation and production level.
Microsoft's Problem with Security
Almost as fast as coding practices, approaches, and paradigms change to account for previous weaknesses and flaws, new exploits and attack vectors are hatched and unleashed upon the world. For Microsoft, the inherent problems of security are compounded by a couple of other, significant, factors.
First is the fact that Microsoft has done a very successful job of creating what many have termed a “culture of amateurism.” Visual Basic 6, for example, once claimed over a million users because it was a programming language that was easy enough for the masses. ASP.NET Web Forms, in turn, tried to capitalize on that success by making it much easier for VB6 developers to begin magically coding Web Forms that would let their applications come to life on the web—without any need for understanding of how HTTP really works. The same could also be said for SQL Server which runs insanely well out of the box ,so much so that large numbers of small to medium businesses run successful SQL Server installations with critical business data yet no they have no DBA and (in many cases) very sparse DBA-related skills among their IT staff.
With this culture of amateurism, Microsoft helped make technology much more approachable and has done a great deal to advance the adoption of IT within business. That, in turn, has helped build business and even help create careers (see my previous briefing where I outline how I entered this field as one of these amateurs; just in case you think I'm being snobby or elitist).
The problem, of course, is that security is a complex enough issue even for professionals - let alone for people who dabble in systems administration or development or who are just getting a start without adequate guidance and supervision. This, in turn, creates a landscape where oversight, mistakes, and inexperience can create security nightmares.
Couple this situation with the fact that the press typically loves stories that blame Microsoft for security failures, and it's easy to see why Microsoft sometimes takes what appears to be draconian measures when it comes to security. However, by doing so, they're simply protecting themselves by protecting developers and admins who don't know (or care) enough to protect themselves. And that, frankly, is a liability for those of us who do know and care enough.
Microsoft's task, therefore, is to create a “just right” approach to security that addresses the fact that some professional developers and admins will simply never care enough about security, while not shackling the rest of us with the constraints imposed because of the lazy or non-caring.
Contributing to Developer Negligence
Recently I was engaged by a client to review some performance problems it was having with a Facebook application they want to roll-out for integration with their existing site. The Facebook application in question was seven months over-due from the developer, only contained 6,000 lines of code, yet strangely took 5-8 seconds to load what should otherwise be static pages.
After getting access to the code to review from a performance perspective, I couldn't help but notice the following (which jumped out at me in that the designer as the search field literally had Request.QueryString\\["Search"\\] as the text):
<input id="SEARCHSTR" name="SEARCHSTR" type="text"
value='<%= Request.QueryString\\["SEARCHSTR"\\] %>' />
value='<%= Request.QueryString\\["SEARCHSTR"\\] %>' />
Given how easy this (and similar direct-echoing of user-supplied input) could be to exploit from an XSS (and even CSRF) perspective, I brought this up with the development company that created this application. Their response was (in their words) that they were safe from XSS and CSRF since IIS doesn't allow angle-brackets to be sent as part of a Request.
Ignoring the fact that ASP.NET's ValidateRequest directive (not IIS) is what's giving them this seeming “protection,” the bigger issue here is that these developers are 100% relying upon ASP.NET to provide them with security. As such, instead of HTML encoding any output that could have been monkeyed with by end-users (or hackers), these developers tested a few “hacks” against the system, saw that ASP.NET's ValidateRequest was detecting and blocking potentially harmful content, and decided that their job was done.
The problem with that though, is that over the years, ASP.NET has increasingly had to compensate for the fact that developers commonly do NOT encode potentially dangerous (user supplied) content. As such, Microsoft has taken on more of a responsibility for making sure that content written out in the response stream is encoded by default. Consequently, some developers are increasingly becoming more and more confident that they do NOT need to bother with HTML encoding because the Framework has them covered. And that's a bad place to be, both because encoding is ultimately the developer's job and because Microsoft has inadvertently been enabling bad practices by trying to address bad practices.
ASP.NET MVC Preview 2 Changes to Prevent JSON Hijacking
Phil Haack recently blogged about a very subtle JSON vulnerability and a related JSON Hijacking problem that can hijack sensitive data returned by a JSON GET. He outlines the problem very well and in concrete detail - and even supplies a sample project you can use to see the vulnerabilities in action yourself. So I won't detail the issue here, other than to say that he raises a very serious specter, which is that GETs for JSON data can be prone to a very subtle, yet vicious, security vulnerability.
Given Phil's role in defining the direction of ASP.NET MVC, it's therefore not surprising to see that Preview2 of ASP.NET MVC 2 (up on codeplex.com) introduces a breaking change to address this. Specifically, as the release notes outline, an ASP.NET MVC JsonResult will now only respond to HttpPost requests.
Personally, my initial reaction was that this is a bad move because it seemingly takes security decisions away from developers and dictates how things should be done. Moreover, considering how obscure this exploit can be, and the fact that using HTTP GETs are faster for JSON results anyhow, this breaking change seems a bit heavy-handed.
That said, Microsoft also can't afford to ignore the potential for this vulnerability. It could try educating users to beware of using HTTP GETs for JSON content containing arrays of sensitive information to browsers that enable __defineSetter__, but the topic is fairly complex, and they couldn't get a bullhorn big enough to get everyone's attention. Moreover, there are going to be some developers that will just never care enough about this issue to research it—even if it were placed right in front of them.
So, sadly, I hate to say that I agree with Microsoft’s decision to block HTTP GET requests for JsonResults by default, as long as there's an option to overcome the default when needed. The release notes say that you can modify this behavior yourself by over-riding the new JsonRequestBehavior property of ASP.NET MVC's JsonResult. My hope is that the MVC team will release a solution that allows us to decorate JsonResult controller actions with an attribute that flags them as GET-able because that would be an easy way to let developers take control of their own security needs while giving them easy flexibility.
The problem, of course, is that when it comes to security, by taking even this step to address a real, viable, security issue, some developers will now think that they're safe to send sensitive info via JSON—as long as they're using a POST—which isn't always true.