DWR Version 2.0 Released
After much waiting, we can at last, say - DWR Version 2.0 has been released.
There are a lot of new features in version 2. Probably too many because it took a while, and it's going to take a few weeks for the documentation to catch-up. Version 1.0 and 1.1 had very good documentation, and we're determined not to let it slip.
Reverse Ajax particularly is doing a lot of very hard things. It has to cope with buggy browsers, buggy web-servers, buggy proxies, multi-threading, multiple languages, and the fact that the web was never designed to do this in the first place. There may be some bugs in the edge-cases, but we'll be fixing them soon. If you do find anything wrong, please report it.
You WILL be coming to my JavaOne talk
Thanks to my elite CSRF skillz, and the fact that you're reading my blog, I've just scripted a form in the background and posted it to the JavaOne Schedule Builder to book you in to my JavaOne session entitled: "Hands-On DWR". It will be good to see you there.
This presentation digs into many advanced DWR features such as Reverse Ajax and the JavaScript technology proxy APIs. The session creates a web-based multi-player game, almost from scratch, illustrating how straightforward it is to create advanced effects with minimal coding. By demonstrating advanced page manipulation and server-based control of browsers, the game shows how to update any web application to react to server changes.
* Footnote to the humor impaired: I'm not serious. Breaking into systems using JavaScript form wrangling is wrong.
** Additional Footnote: And it would never work, blog aggregators strip out JavaScript.
*** Additional additional footnote: Quite right, you should use a 1x1 pixel gif with a custom GET request to effect the form submission to bypass the blog aggregators script filters.
**** A3 footnote to the humor impaired: I'm still not serious.
***** A4 footnote: But if you don't believe me, check for yourself, and while you're there book into session TS-6410 anyway.
CSRF, Anti-DNS Pinning and NTLM
Mark Goodwin has written a neat discussion of the extra problems that CSRF causes when used alongside DNS pinning attacks and against intranets that use NTLM authentication (AKA Integrated Windows Auth)
The short version is that you might be able to use CSRF and anti-DNS pinning attacks to steal resources from an intranet, including those that need auth NTML authentication.
Getahead predates DWR by quite a while, and Mark has worked with me on a few projects. For the past few years he's been a serious security head, and he's just started blogging.
I'm not going to link to all his posts, so if you are interested in security; subscribe, and I'll get on with the Ajax and Java stuff.
New DWR Release - 2.0 RC4
I created this blog a few years ago specifically to announce releases of DWR, but I skip announcing new releases too often - I'm making amends: 2.0 RC4 RC4a (see below) is out of the oven.
What's new?
- The biggy is Guice support. If it wasn't for the fact that we could add this in without touching the core of DWR, I'd say this was too big a change at this point in the release cycle, however Tim Peierls (who you might know from this project) has done a stack of work to make DWR and Guice play really well together. You can read more about the background on Tim's blog.
- Security: The Fortify review highlighted some areas where DWR was lacking. You can read more about what DWR now does to protect you in the DWR security documentation.
- Reverse Ajax: There have been some cases where reverse ajax has not been as stable as it should be. I hope that most of those are now behind us.
What's TODO before 2.0 final?
Not a lot. Some dwr.util fixes. Some documentation.
TIBCO have been fantastic in supporting DWR, and I'm hoping to add a demo of GI providing some UI components that are populated using DWR to the final demo war file.
Ahmed Hashim has submitted a SingletonCreator which, like Guice support can be added without touching any core code, and that's about it.
I'm hoping for a final release in a week or so.
Update: Make that RC4a. Some fixes we put in for bugs in RC3 caused errors in IE7. They are now cleared up.
Java 7 Idea: Extensible Strings
In some ways it's a shame that java.lang.String is marked 'final' in Java. If it wasn't final, you could inherit from java.lang.String to create strings that had some extra features, or you could extend with a marker interface to declare that a String has some property, for example it would be neat to be able to track if a String had been:
- Checked for dangerous characters from the web
- Internationalized
- Processed by some system
Allowing marker interfaces like this could lead to some nice extra type-checking:
public SafeString checkForUnsafeCharacters(String s) {
// do some checking and throw or create a SafeString
}
public void process(SafeString s) {
// do something knowing that the developer can't forget
// to check the string before it is passed in
}
Marker interfaces on strings can be a handy way to declare that this string has some properly that normal strings don't.
However there are at least 2 good reasons why java.lang.String is final:
- Security: the system can hand out sensitive bits of read-only information without worrying that they will be altered
- Performance: immutable data is very useful in making thing thread-safe.
So is it possible to have the best of both worlds - to allow marker interfaces and additional properties without breaking assumptions about the immutability of the string itself. And, is this possible without breaking backwards compatibility?
In Javas 1 to 6, java.lang.String is defined like this:
public final class String {
public int length() ...
... // other methods and properties
}
I think we might be able to safely change this to:
public class String {
public final int length() ...
... // everything made final
}
I don't think this breaks backwards compatibility anywhere because it mostly legalizes something that would previously have been a compile error, and the immutability of the core String is as unbroken as it was in Javas 1-6, although obviously the same guarantees could not be made about all extensions.
Declaring finality in this way allows marker interfaces, which might in some cases allow developers to create APIs that enforce some properties on strings that might previously have been forgotten.
Can anyone think of anything that I've overlooked?
How to Protect a JSON or Javascript Service
There have been lots of explanations recently of the dangers of JSON or JavaScript remoting. This post is about what you can do to protect your scripts.
The Problem
The issues have been explained before, so I'm going to assume some knowledge of the problem. If you're not sure, some stuff to read:
- I blogged that JSON is not as safe as people think it is, and updated it with more issues the next day. I've also written about CSRF too.
- Dan Morrill has written an excellent and lengthy summary. The fixes are focused on GWT, but the issues are the same for everyone.
- Brent Ashley has just published on developerWorks, about the future of cross-domain requests. The article is tangentially relevant, but there is a particularly good set of linked articles.
The Solutions
So what are the solutions? I think there are 3 options. Each has their pros and cons:
- Use a Secret in the Request
- Force pre-eval() Processing
- Force POST requests
This post is a shortened version of the detailed description of what DWR does If you are interested in the options DWR takes and how you can configure it, you should read page.
1. Use a Secret in the Request
If you can only support one of these protections, this is the one to chose. Including a secret in the request allows the server to reject the request as invalid before any actions take place. It is common to include the secret in the URL, however this is a slightly vulnerable position for a secret since it is likely to turn up in web server log files and so on.
It is possible to use cookie values like PHPSESSIONID or JSESSIONID read using Javascript as the secret. The browsers cross-domain rules should prevent attackers from discovering this cookie. However this method will stop working as people begin to switch to using HttpOnly cookies. So it is better to start with a separate secret.
2. Force pre-eval() Processing
Since <script> tag remoting does not allow you to process the JSON or Javascript before it is eval()ed you can protect your JSON by forcing it to be manipulated before eval(). All 3 of these techniques will prevent your request from being pure JSON, however you may rank security above purity. There are 3 ways to do this:
- Wrap the JSON in a comment. For example,
/* { 'data':'protected' } */. When this is eval()ed, there will be no result, however if you have fetched the data using XHR or iframe, you can do some string manipulation before eval() to remove the leading /* and trailing */.
This method is good for plain JSON, however if you are using Javascript which could contain /* comments */, then you should not use this technique because comments in Javascript do not nest. - Prefix the script with '
while(1);' Since this is an infinite loop, if causes browsers to hang, and maybe give an error message. Either way the script does not get executed.
There is a potential vulnerability that some browser may allow you to override the action of while using something like this: 'function while() {}'. However I don't know of any such browser.
Google use this method to protect data in GMail. 'while(1);' is possibly better than 'while(true);' in case there are any browsers that allow you to redefine truth. - Prefix the script with '
throw new Error("message");'. This is a neat solution in that it allows you to explain what is wrong to users that get the message by mistake. DWR uses this method.
It is potentially vulnerable to some browser allowing an attacker to redefine the Error or String constructors to prevent the throw from happening, however this does not work on any browser that I know of, and it's hard to see how it could happen.
3. Force POST Requests
Since browsers use GET to process <script> tags, you can prevent <script> tags from working by denying GET requests for some JavaScript resource. This is the most common solution, however it is also perhaps the weakest.
Firstly XHR-POST doesn't work with older versions of Safari, so some support for GET is often useful.
More importantly future versions of Firefox are touted to include cross-domain XHR support. While we don't have exact knowledge of how this will happen, it would be foolish to base your security plans on this technique holding up.
Finally, we're working in an environment where new possibilities are popping up every day - betting your security on a system that works more by fluke than design isn't a great idea in my opinion.
By default DWR denies POST requests for belt and braces security, however this is customizable to allow support for older versions of Safari.
Good marks for security features in DWR
Fortify software have been investigating security features in the most popular Ajax frameworks, and DWR v2 comes out very well indeed. From the paper:
We analyzed 12 popular Ajax frameworks, ... We determined that among them only DWR 2.0 implements mechanisms for preventing JavaScript Hijacking.
You can download the entire paper in PDF format.
I'll be posting a detailed explanation of what DWR does to secure your data along with other options soon.
DWR 2 is currently at Release Candidate 3. We hope a final release will be ready in a couple of weeks.
Free Seminar
I'm doing a free evening seminar on DWR, Security and Accessibility in a few weeks time, on Wednesday 25th April from 18:30.
It's hosted by Skills Matter at: 1 Sekforde St, London EC1R 0BE, UK [Google Maps] [Live.com]. Entry is free but you need to register.
We've got 90 mins for the seminar, but I think there is a good chance we'll end up spending 30 mins on questions, so the talk will probably be about an hour.
And there's a plan for beer afterwards.