Silverlight 1.1 (Alpha) cross domain webservice access makes mashups tricky

Any web mashups, by definition, require cross-domain calls. Those cross-domain calls may happen on the client (in the browser) or on the server. Regardless of the client technology (AJAX, Flash, Silverlight, etc.), cross domain calls on the client are always more complex that server-side cross-domain calls, and for good reason. It's tricky in AJAX, and it's downright difficult in Silverlight. You'll know that Silverlight development has become more widespread when you hear a lot more complaints about this problem.

I previously wrote about using a static port to eliminate this problem when you're calling back to your own server but Silverlight is detecting a cross-domain call. That's caused by the ASP.NET Development Server running the different projects on different ports (e.g. website on localhost:1234 and webservice on localhost:5678), and you can work around it by just putting the website and webservice in one project with a static port. However, there are plenty of times when you'll want to make a cross-domain call, so we've got to get this figured out.

While helping Rob Conery work through some problems connecting to Amazon Web Services this past week, I wrote up some notes on the issue.

Silverlight intentionally blocks cross domain access

Silverlight intentionally forbids cross domain access, so unless webservices.amazon.com served up the page with the Silverlight control, it’s not going to allow access. That’s a pain from a developer point of view, but from a security point of view it makes complete sense. Otherwise a the Silverlight control could be used to turn a user’s browser into a “zombie” which could roam the entire Internet and local intranet without the end user’s knowledge, doing all kinds of bad things (posting spam on forums, DDOS attacks, modify the local router via web access, etc.).

It's important to understand that this is an even worse case than a simple cross-site scripting (XSS) attack, which steals information from one site to pass to another. In addition to information security issues, a cross-domain vulnerability is like an unpatched virtual machine running on a patched host, since malicious net access code would be more like an out of control virus with full Internet access.

A simple proxy through XmlHttp isn't likely to work

XmlHttp in both Firefox and IE7 (and XmlHttpRequest in IE6) are pretty locked down by default, so it’s hard to come up with a cross browser solution that will work on a default browser configuration. For example, Firefox only allows it if the script is signed, and IE7 applies security zone policies. It's hard to find a simple cross browser solution here.

Server-side proxies are a simple solution

You can use a server side proxy, of course, which gets around all these restrictions because Silverlight is calling back to the originating domain.

The JSONP workaround

You can use JSONP to do a client side proxied call which goes through JavaScript but doesn’t use the XmlHttp stack. The basic concept is that the browser security model allows you to reference a JavaScript source from any location, so JSONP dynamically adds a script element with a src set to the cross domain URL you want to access. The information returned by that URL isn’t JavaScript, but it doesn’t matter; the JSONP code which created the script element just reads the contents and destroys the script element when it’s done. That’s easier for web services which support JSONP natively – del.icio.us, Yahoo – but it can be done against AWS via some libraries.

What I think Microsoft should do

The Silverlight team should do one or more of the following:

  1. Document this more, preferably in the Silverlight documentation on MSDN
  2. Add a client configurable whitelist of domains to which cross-domain calls are allowed
  3. Have a list of "certified" safe domains to which cross-domain calls are allowed (Microsoft, Google, Amazon, Flickr, del.icio.us, etc.).
  4. Offer a proxy service, perhaps reimbursed by the target domains

UPDATE: I heard there will likely be a solution of some kind to this problem in a forthcoming Silverlight release.

References:

A pretty good article on JSONP with a sample which hits AWS: http://www.devx.com/webdev/Article/30860/1954

A sample which hits AWS via JSONP (bonus points for using XSLT to convert AWS XML responds to JSON, which isn’t as useful for you since in Silverlight XML’s easier to read than JSON): http://www.kokogiak.com/gedankengang/2006/05/consuming-amazons-web-api-directly.html

My previous blog entries on the topic - http://weblogs.asp.net/jgalloway/archive/2007/06/14/calling-an-asmx-webservice-from-silverlight-use-a-static-port.aspx, http://weblogs.asp.net/jgalloway/archive/2007/05/08/silverlight-cross-domain-access-blocked-use-a-server-side-proxy-or-xmlhttprequest.aspx

7 Comments

  • Wouldn't it be easy to set up a WS-Router together with your Silverlight app?

  • Except that the cross-domain blocking that is used in Javascript (the model they seem to have copied) is flawed.

    I regularly use cross-domain Javascript in my applications. You can just drop another "script" tag into your HTML dynamically and get it to call Javascript on another server.

    Blocking cross-domain access is a quick way to block useful applications.

    Coming up with a secure solution to cross-domain access is the clever way that a bright person would do it.

  • I can't see where in the example it access AWS via dynamic script tag though? Looks like they only do Yahoo Web Services via dynamic script tag...

  • @Morgan - You're talking about setting up a server-side proxy (via the WS-* stack), right? That works, but it puts unnecessary load on the server, slows down the response, etc. It'd be preferable to be able to talk directly to webservices from the Silverlight client.

  • "Regardless of the client technology (AJAX, Flash, Silverlight, etc.), cross domain calls on the client are always more complex that server-side cross-domain calls, and for good reason."

    It's true that it's more complex, but it is not similarly impossible in all three technologies cited.

    (Adobe Flash Player has supported cross-domain access for almost five years now. Lots of existing web services specifically permit cross-domain access from SWF this way... doesn't require a repackaging of the data form, just permission for its use by clients from other domains.)

    jd/adobe

  • @John Dowdell - Right, sorry about that. I meant that at some level there's more complexity when handling cross domain access on the client. Flash solved this problem years ago, as you pointed out, so the Flash dev team dealt with the complexity rather than web developers, but it still required some extra smarts compared with a simple server-side proxy.

  • Aw, this was a very good post. Taking a few minutes and actual effort to
    make a superb article… but what can I say… I procrastinate a lot and never seem to get anything
    done.

Comments have been disabled for this content.