Over the holidays I had a chance to talk to some of my old compadres from the XML team at Microsoft and we got to talking about the JSON as an alternative to XML. I concluded that there are a small number of key reasons that JSON is now more attractive than XML for kinds of data interchange that powers Web-based mashups and Web gadgets widgets. Expect a series of posts on this later today.
I wasn't sure I was going to write about this until I saw Mike Arrington's blog post about a GMail vulnerability which implied that this is another data point in the XML vs. JSON debate. On reading about the vulnerability on Slashdot I disagree. This seems like a novice cross site scripting vulnerability that is independent of JSON or XML, and is succintly described in the Slashdot comment by TubeSteak which states
Here's the super simple explanation1. Gmail sets a cookie saying you're logged in2. A [3rd party] javascript tells you to call Google's script3. Google checks for the Gmail cookie4. The cookie is valid5. Google hands over the requested data to youIf [3rd party] wanted to keep your contact list, the javascript would pass it to a form and your computer would happily upload the list to [3rd party]'s server.
Mitigations to this problem are also well known and are also summarized in another Slashdot comment by buro9 who writes
When you surface data via Xml web services, you can only call the web service on the domain that the JavaScript calling it originates from. So if you write your web services with AJAX in mind exclusively, then you have made the assumption that JavaScript is securing your data.The problem is created at two points:1) When you rely on cookies to perform the implicit authentication that reveals the data.2) When you allow rendering of the data in JSON which bypasses JavaScript cross-domain security.This can be solved by doing two things:1) Make one of the parameters to a web service a security token that authenticates the request.2) Make the security token time-sensitive (a canary) so that a compromised token does not work if sniffed and used later..
The surprising thing is that I'd assumed that the knowledge of using canary values was commonplace but it took a lot longer than I expected to find a good bite size description of them. And when I did, it came from co-worker Yaron Goland in a comment to Mark Nottingham's post on DOM vs. Web where Yaron wrote
There are a couple of ways to deal with this situation: Canaries - These are values that are generated on the fly and sent down with pages that contain forms. In the previous scenario evil.com wouldn't know what canary site X was using at that instant for that user and so its form post wouldn't contain the right value and would therefore be rejected. The upside about canaries is that they work with any arbitrary form post. The downside is that they require some server side work to generate and monitor the canary values. Hotmail, I believe, uses canaries. Cookies - A variant on canaries is to use cookies where the page copies a value from a cookie into the form before sending it up. Since the browser security model only allows pages from the same domain to see that domain's cookie you know the page had to be from your domain. But this only works if the cookie header value isn't easily guessable so in practice it's really just canaries. XMLHTTP - Using XMLHTTP it's possible to add HTTP headers so just throw in a header of any sort. Since forms can't add headers you know the request came from XMLHTTP and because of XMLHTTP's very strict domain security model you know the page that sent the request had to come from your site.
There are a couple of ways to deal with this situation:
Canaries - These are values that are generated on the fly and sent down with pages that contain forms. In the previous scenario evil.com wouldn't know what canary site X was using at that instant for that user and so its form post wouldn't contain the right value and would therefore be rejected. The upside about canaries is that they work with any arbitrary form post. The downside is that they require some server side work to generate and monitor the canary values. Hotmail, I believe, uses canaries.
Cookies - A variant on canaries is to use cookies where the page copies a value from a cookie into the form before sending it up. Since the browser security model only allows pages from the same domain to see that domain's cookie you know the page had to be from your domain. But this only works if the cookie header value isn't easily guessable so in practice it's really just canaries.
XMLHTTP - Using XMLHTTP it's possible to add HTTP headers so just throw in a header of any sort. Since forms can't add headers you know the request came from XMLHTTP and because of XMLHTTP's very strict domain security model you know the page that sent the request had to come from your site.
I guess just because something is common knowledge among folks building Web apps and toolkits at Microsoft doesn't mean it is common knowledge on the Web. This is another one of those things that everyone building Web applications should know about to secure their applications but very few actually learn.