Click here to Skip to main content
Click here to Skip to main content

Easy Cross-site Scripting using the easyXDM Library

By , 17 Aug 2009
 

Introduction

Even though we, for security reasons, most often do not wish pages from different domains to be able to communicate, sometimes we do. And then, we discover that there is no 'proper' way to do so - the current standards and the current technologies are built to disallow it.

So we turn to workarounds, we use dynamic script tags included from external domains, we use JSONP, or we try our best using postMessage or the IFrame URL technique. These solutions often become quite complex and fragile, and transporting the pure string messages between the domains might very well end up making up most of your code.

Well, easyXDM (cross domain messaging) is now here, and it is meant to reduce the amount of work needed for cross-site communication - actually, it can do this in as little as 4 lines of code! And, if you want to be able to actually call methods across the boundary, well, that only takes 3 more!

See here for a demo of some of the functionality presented.

Background

This library was designed and built due to my company needing to expose an interface to one of our AJAX-applications. This application would have to be launched, and controlled to a certain degree from other web applications implementing our API, and our wish was to make it as reliable as possible (work both on IE6 and on FF3.5), and as easy to implement as possible. This has led us to easyXDM, which we are now publishing under an MIT-license.
easyXDM was previously called easyXDM, but due to it often being mislabelled as malware (XSS), we decided to change its name.

The library lives at easyxdm.net, where you can easily get access to the source, ready made packages and also the extensive documentation. In the documentation you also find several interesting demos.

Using the Code

The code presented here assumes that you have a website with a method (an API, weather service, stock service ..) that you want to expose. In this example, the method is called _privateDoMagic: it takes three arguments, and will return a JSON object.

What we want the API consumer to be able to do is call this method, like any other JavaScript method, and get the result back - something like this:

remote.doMagic('argument1',2,'three',function(result){
    // Consume the result
}

So first of all, we'll assume that the easyXDM library is present on both the page providing the API and the page consuming it, and that the JSON object is also present in both, either natively or via the json2 library.
With easyXDM you can actually use the following to load json2.js only when needed:

easyXDM.DomHelper.requiresJSON("/json2.js");

easyXDMs base functionality is that it provides a reliable mechanism for transporting string messages between domains, and it uses different techniques to do this depending on the browser.

But what easyXDM is also able to do is to take an interface configuration, where you describe the methods you want to expose, and the methods you want to consume, and transform it into working code - easyXDM does all the plumbing so that you can call the method in one domain, have the method call with arguments sent to the other domain, and have the result returned to the invoking method.

The interface is two-way, and both sides of the interface are able to expose and consume methods. The only difference in the configuration has to do with which side sets up the channel.

To expose the above-mentioned _privateDoMagic method, so that it can be consumed, all we need to do is insert the following code:

var remote = new easyXDM.Interface({}, {    
    local: {
        doMagic:{
            method: _privateDoMagic
        }
    }
});		

Here is the same code in a more compact form:

var remote = new easyXDM.Interface({},{local: {doMagic:{method: _privateDoMagic}}});
What we are doing here is creating a new easyXDM.Interface, using default values for our easyXDM.Channel, and an InterfaceConfiguration exposing a single method.
By omitting the settings for the channel, we are indicating that the library should use the default settings combined with the settings provided by the consumer.

That's all for the API provider!

Now, to consume this method, the following code is needed:

var remote = new easyXDM.Interface({
   local: "../hash.html",
   remote: "http://apiprovidersdomain.com/api.html"
},{
    remote: {
        doMagic: {}
    }
});

And again in compact form:

var remote=new easyXDM.Interface({local:"../hash.html",
	remote:"http://apiprovidersdomain.com/api.html"},{remote:{doMagic:{}}});

Again, we create an easyXDM.Interface, this time supplying the channels configuration in the first parameter.
The supplied settings here are the path to the local copy of hash.html, and the URL to the API providers endpoint.

And that's it.

The consumer is now able to call the method locally using:

remote.doMagic('argument1',2,'three',function(result){
    // Consume the result
}

and have the result returned.

Good luck! Or actually, with this library, you don't need it! :)

Points of interest

If you look at the source code, you will actually see that the implementation is quite simple. It's also well documented, and experienced developers should be able to understand how it works quite easily.

The debug version includes extensive tracing, and you can easily see what's going on. This is used in the examples.

History

  • 24th June, 2009: Initial post
  • 14th August, 2009: Article updated

License

This article, along with any associated source code and files, is licensed under The MIT License

About the Author

Øyvind Sean Kinsey
Software Developer (Senior) BRIK
Norway Norway
Member
I am a partner at BRIK where we create rich web sites focusing on content, enabling non-technical users to publish a variety of media easily.
We are also the technical partner on ExorLive, a web application for planning and tracking workouts.
 
I have worked mainly with .Net, MySQL and Javascript, and today most of my work is centered around creating rich and effective frontends with Javascript backed by Javascript-enabled webservices.
 
I am also the manager of the easyXDM project, enabling web developers to easily expose javascript API's.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat about JQuery integrationmembersofter9 Nov '09 - 9:11 
What about to integrate this as a jquery plugin?
Some of the things would not be needed anymore as they can rely on JQuery i.e. working with events.
So I assume the minified code would less than 4KB
AnswerRe: What about JQuery integrationmemberØyvind Sean Kinsey9 Nov '09 - 9:23 
You mean increasing the size from 4kb to 23 kB(jQuery + easyXDM), as well as introducing jQuery as a dependecy for all the sites using prototypejs, ExtJs etc? I don't think so Smile | :)
 
As it is now the library is not dependant on any other library, and there isn't really that many bytes to be saved by doing so.
 
But off course, it is licensed under the MIT license, so anyone can rewrite it to fit their chosen framework.
GeneraleasyXSS has now changed its name to easyXDMmemberSeanKinsey9 Aug '09 - 13:33 
Due to people thinking it was some kind of hacking tool, it has now been renamed to easyXDM - easy cross-domain messaging.
It has also gone through a few versions and is now currently at 1.5.
The online docs has come a long way and is now available at http://easyxdm.net/docs
GeneralExcellent work,memberMichael Coyle29 Jul '09 - 10:05 
Have to hand it to you, excellent work on this.
The documentation is a little thin, and the examples can be a little hard to follow for someone such as myself without a lot of JavaScript experience. However I managed to work my way through this and implemented a solution to a problem I was having where your code was the holy grail of the solution.
 
I would suggest that you put this is "advanced" category.
GeneralRe: Excellent work,memberSeanKinsey29 Jul '09 - 10:14 
Thank you, I appreciate the feedback Smile | :)
 
I'm with you on the documentation, somehow its not as fun to write the docs that it is to write the code, but I know that if I want people to use it then it is needed. For now I have focused on examples.
 
If you know of anything that need special attention please let me know!
GeneralRe: Excellent work, [modified]memberSeanKinsey1 Aug '09 - 2:06 
I have just now published a new version, this contains both generated class documentation and .debug and .min versions of the libary.
The library has also been restructured and should be somewhat easier to understand.
 
Its currently available at http://ohloh.net/p/easyxss which will be its new home away from home (http://easyxss.net)
 
modified on Saturday, August 1, 2009 10:47 AM

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 17 Aug 2009
Article Copyright 2009 by Øyvind Sean Kinsey
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid