Monday, June 25, 2007

A couple of different threads that triggered in the past two days prompted this post. 

One involved a Silverlight enthusiast who has been using the BrowserHttpWebRequest class (a new class, similar to the System.Net.HttpWebRequest class in .NET, introduced in the Silverlight .NET libraries that makes use of the underlying browser stack to make web requests) to make requests to a web service in a different domain. 

Result: An exception that says "Cross domain calls are not supported by BrowserHttpWebRequest".

The other involved an AJAX developer trying to call a web service from JavaScript from another domain.  Again a similar cross-domain script error raised in the browser with a "Access denied" message.

The standard paradigm on the Internet is NOT to allow cross-domain scripting.  Cross-domain scripting is nothing new - it has been there ever since JavaScript has been around.  It is dangerous in that it allows a malicious user to inject code into a page from a different domain.  

There are few basic rules when JavaScript executes on a web page:

  • Any JavaScript code that runs within a page runs within the context of THAT page.  Which means that the JavaScript running on a page also gets to call back the same server from which the page loaded, be able to modify DOM elements of the page, be able to get to all the user input, headers, cookies, form fields, etc. on that page.
  • JavaScript included from a seperate JS file is only physically seperate.  When the page loads and a SCRIPT SRC is encountered, the JavaScript file is requested for, downloaded and then the code is included as part of the entire JavaScript.  In fact, execution of the script starts as soon as the file is downloaded completely.

Now having stated the above - let us assume we allowed cross-site scripting.  That would mean a user would be able to include (say as part of a blog's comments) a SCRIPT SRC pointing to a JS file on a different domain.  This part is actually allowed by the browser.  However when the remotely loaded script tries accessing or posting back any of the data on the page (that has loaded from a different domain), it is disallowed and an Access Denied message occurs.  This basically protects the script from stealing any data and posting it back to a different server without the knowledge of the user.

Check the Wikipedia article on Cross-Site Scripting (XSS) at http://en.wikipedia.org/wiki/XSS and go through some of the famous exploits mentioned there.

But I want to build mashups!

Sure, you still want to make use of all the power of AJAX or Silverlight and get services from multiple domains mashed up on the browser.  The solution is quite simple.  Use a bridge pattern to access the third-party services.  This basically means a "proxy" service sits on the same server (as the page on which the JavaScript/Silverlight component is loaded) and any callbacks happen to a service on the same server.   This service can then make a server-to-server call to other web services on third-party domains.  Once the data is received, it can be sent back to the client.

This is a standard pattern for accessing cross-domain services.  The Silverlight team is also working on a solution to make cross-domain posts safely possible in Silverlight 1.1 - but that is something that is only going to be in the future (hopefully).  Currently, Silverlight too blocks cross-domain calls. 

If you think the above makes sense, you are all set to write your code.  If you are the type that likes to see some reference code, try this article: http://dotnetslackers.com/columns/ajax/MashitUpwithASPNETAJAX.aspx

A good explanation is also available at the Yahoo! developer website: http://developer.yahoo.com/javascript/howto-proxy.html

posted on Monday, June 25, 2007 11:38:45 PM (India Standard Time, UTC+05:30)  #    Comments [1] Trackback