Hi,

we figured out some more advanced CSRF protection for our app to be
built. I wrote some short spec from the current perspective. If you
have some notes or enhancements please let me know.

thx, andi

GWT CSRF Security
=================

There is a good explanation of different security leaks that are
possible in
an AJAX application: 
http://groups.google.com/group/Google-Web-Toolkit/web/security-for-gwt-applications
.


Basic Approach
--------------

To prevent CSRF Google suggests:

    If you are using the RequestBuilder and RequestCallback classes in
GWT,
    you can implement XSRF protection by setting a custom header to
contain
    the value of your cookie.

This is generally a good idea, especially since there is a simple
implementation
for validation on the serverside.


Extended Approach
-----------------

If we assume there could be a persistent XSS hole in our application
by
accident, the basic approach is no longer secure. An attacker could
inject
JS code which runs in our own domain-scope and is able to access the
sessionid
of any user where the script runs at. In result of that, this attacker
could
for example send sessionids to a third party server.

Simple (more paranoid) solution is to publish session-cookies via
HTTPONLY
http://www.codinghorror.com/blog/2008/08/protecting-your-cookies-httponly.html
This denies all - including our own - scripts to access the session
cookie.

Now we prevent anybody to steal our sessions, but we are also unable
to use
the sessionid as CSRF protection. Therefore its necessary to use a
different
token for this kind of protection. We call it ``X-Request-Token``,
which is
returned from the server besides the ``Set-Cookie`` header.

``X-Request-Token`` can be a custom implementation of any unguessable
content.
E.g. there can be (pseudocode)::

    crypt(now() + "#" + user_id)

and validation could be (pseudocode)::

    boolean is_valid(request_token, user_id) {
        try {
            parts = decrypt(request_token).split("#");

            return user_id == parts[1]
                    && ALLOWED_TIME_DIFF > (now() - parts[0])
        catch (ignored) {
            return false
        }
    }

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to