May 19, 2009

Back to Basics - Cross Site Scripting - How web 2.0 mashups really work?

Cross Site Scripting the term may not be familiar to many of us. Instead let me explain this in a lay man's terms - Web 2.0 mashups. 

Web 2.0 mashups - Making the browser connect to various sources (rss, webservices) on the internet and cook up a usable application out of all these sources. A Web 2.0 mashup is typically a html page with some javascript which make all this happen.

A simple example of a mashup could be using a feed from craigslist (or any rent/sell house site) and map the listings on a map (say google map). The services which are used in this example are rss feed from the source, reverse geo lookup (address to co ordinate converstion service from google map) and google map itself. All done in a html page without the need of any server.


Now that we know about Web 2.0 mashups we should now move on to Cross Site Scripting.

Firstly lets understand what is the main hurdle in cross site scripting. Its called as Single Origin policy, if a page is loaded from xyz.com and tries to send a ajax request to abc.com, the browser does not allow it. This is not a bug but a feature, for security reasons. 





If this is so, how can any one use google services directly from the webpage which are not hosted on google.com. The answer is simple JSONP. You should know about JSON before you proceed ahead.

Even though the browser restricts sending ajax requests to other domains, it allows javascripts (even at runtime) from other domains in the html code. 

Lets take a very simple example, one of the services http://www.freehoroscope.com/json gives out a JSON string like this

[
  {"date":"12/12/2008", 
    "Aries":"The day looks good for you....",
    "...","...",
    "Cancer","You will meet some one special today....",
    ".....","....",
    "Sagitarius","Career front there would be good news for you...."
   }
]

Now a javascript eval() function could instantly convert this text into a javascript object and this object can be used to create daily horoscope html.

The problem is I am serving my site from xyz.com and I can't send ajax request to http://www.freehoroscope.com/json. 





Solution is instead of ajax request, I embed a javascript (using dom operations) in my html code at run time 
(div.innerHTML="<s cript src="' http://www.freehoroscope.com/jsonp?callback"="printHoro'>").

Notice I am calling a slightly different url -  http://www.freehoroscope.com/jsonp (notice the extra p at the end)

Lets see what this url gives out the following javascript - 
--------------------------------------------------------------
var data=[
  {"date":"12/12/2008", 
    "Aries":"The day looks good for you....",
    "...","...",
    "Cancer","You will meet some one special today....",
    ".....","....",
    "Sagitarius","Career front there would be good news for you...."
   }
];
printHoro(data);
--------------------------------------------------------------

Its quite similar to the json response just that the response is put in a variable and the function is added at the end. Notice the function name is the same as what we passed in the query string (The server put this callback name into the javascript it throws out).

What happens now is once the javascript is loaded, it creates a variable data and calls the javascript function printHoro. In short you will have to add the printHoro function which will actually be your call back function to render the horoscope
<>
function printHoro(data){
  document.getElementById("date").innerHTML=data[0].date;
  document.getElementById("aries").innerHTML=data[0].Aries;
  ....
}
< / sc ript>





If you have any questions on this mail it to pune-gtug.googlegroups.com





4 comments:

  1. There is a reason why websites prevent cross scripting. This is a security vulnerability. (Rails for example uses authenticity tokens to prevent this.)

    http://en.wikipedia.org/wiki/Cross-site_scripting

    ReplyDelete
  2. If you are exposing this as a way to use your service, it is a feature.

    If some one else is trying to use this on your site, its an XSS security hole

    One country's freedom fighter is another country's terrorist.

    Btw the good way to prevent some one from using XSS on your site (if you allow people to paste html and that pasted html becomes a part of the final page) is to do "Escaping and filtering"

    ReplyDelete
  3. XDomainRequest (in MSIE 8) and XMLHttpRequest Level 2 (in Firefox 3.5 Beta) are no longer limited by same origin policy, but use their own header based access control to prevent cross site request forging.

    ReplyDelete
  4. While waiting for the next generation of browsers, we found a rather simple trick to secure JSONP calls:

    http://beebole.com/en/blog/general/sandbox-your-cross-domain-jsonp-to-improve-mashup-security/

    ReplyDelete