How to prevent CSRF/XSRF when using RequestFactory

1,034 views
Skip to first unread message

Daniel Cowx

unread,
Nov 30, 2010, 10:38:07 PM11/30/10
to Google Web Toolkit
Hi guys,

I've been using GWT-RPC up until this point, but would like to make
the switch to RequestFactory shortly. I'm a bit confused as to how to
prevent CSRF/XSRF with RequestFactory though.

As per http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ,
up to this point I've been sending the session ID within the *payload*
of each RPC. Works great. Should I be doing something similar with
RequestFactory? Any and all suggestions greatly welcome!

Thanks,
Daniel

David Chandler

unread,
Nov 30, 2010, 11:56:43 PM11/30/10
to google-we...@googlegroups.com
Hi Daniel,

I haven't tested it yet, but I believe you can extend
DefaultRequestTransport as discussed in this thread to set a request
header containing your session ID or other XSRF token:

http://groups.google.com/group/google-web-toolkit/browse_thread/thread/e835c3153bc62f4c/751df0dc6aa7eb40?lnk=gst&q=entitymanagerfactory#751df0dc6aa7eb40

HTH,
/dmc

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

--
David Chandler
Developer Programs Engineer, Google Web Toolkit
http://googlewebtoolkit.blogspot.com/

Sripathi Krishnan

unread,
Dec 1, 2010, 5:39:09 AM12/1/10
to google-we...@googlegroups.com
RequestFactory (and GWT RPC as well) automatically adds a custom http header ("X-GWT-Permutation") to each request. See DefaultRequestTransport.java. In modern browsers, it is impossible to add such a request header in a cross-site manner. Because of this feature, most developers don't need to worry about CSRF - GWT automatically protects them.

However, old versions of flash allow an attacker to set custom http headers, thus bypassing default CSRF protection. If your website has users that use outdated versions of flash, those specific users only would be vulnerable to CSRF. 

If you think this is sufficient risk, you will have to continue sending the sessionid in the request and verifying it on the server. To do so, you can extend DefaultRequestTransport as mentioned by Thomas, and add the user specific session id as a request header. Then, on the server side, match the ids in the session object and the request header. If they are not equal, abort the request.

--Sri

David Chandler

unread,
Dec 1, 2010, 1:55:37 PM12/1/10
to google-we...@googlegroups.com
Sri,

Thanks for the info on X-GWT-Permutation. However, I want to make it
clear that the GWT team doesn't believe this is sufficient protection
against XSRF. The current implementation of RemoteServiceServlet
checks only for a non-null value.

  protected void checkPermutationStrongName() throws SecurityException {
    if (getPermutationStrongName() == null) {
      throw new SecurityException(
          "Blocked request without GWT permutation header (XSRF attack?)");
    }
  }

While the absence of X-GWT-Permutation header likely implies an
attack, this code is not intended to offer general protection against
XSRF.

The current GWT security guidelines[1] recommend the use of a token
passed with each request. In fact, there is new code[2] in trunk as of
last week to make this easier, and we're currently working on docs for
it.

[1] http://groups.google.com/group/google-web-toolkit/web/security-for-gwt-applications
[2] http://gwt-code-reviews.appspot.com/1107801/show

Regards,
/dmc

PhilBeaudoin

unread,
Dec 1, 2010, 1:57:48 PM12/1/10
to Google Web Toolkit


On Dec 1, 2:39 am, Sripathi Krishnan <sripathi.krish...@gmail.com>
wrote:
> RequestFactory (and GWT RPC as well) automatically adds a custom http header
> ("X-GWT-Permutation") to each request. See
> DefaultRequestTransport.java<http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/...>.
> In
> modern browsers, it is impossible to add such a request header in a
> cross-site manner. Because of this feature, most developers don't need to
> worry about CSRF - GWT automatically protects them.

This is really interesting and I was not aware of that feature of
modern browsers. Could you clarify how this works or link to a website
explaining it? (In particular, I'm interested to know how a browser
can prevent malicious javascript to insert this header in a request.)

Cheers,

Philippe

Sripathi Krishnan

unread,
Dec 1, 2010, 2:30:23 PM12/1/10
to google-we...@googlegroups.com
This is really interesting and I was not aware of that feature of modern browsers. Could you clarify how this works or link to a website explaining it? (In particular, I'm interested to know how a browser can prevent malicious javascript to insert this header in a request.)

Here are some discussions on this topic - 
  1. http://www.webappsec.org/lists/websecurity/archive/2010-09/msg00099.html
  2. http://michael-coates.blogspot.com/2010/05/csrf-attacks-and-forged-headers.html
  3. http://stackoverflow.com/questions/2609834/gwt-rpc-does-it-do-enough-to-protect-against-csrf
Please note that the degree of flexibility offered by XMLHttpRequest, and not seen in other cross-domain content referencing schemes, may be actually used as a simple security mechanism: a check for a custom HTTP header may be carried out on server side to confirm that a cookie-authenticated request comes from JavaScript code that invoked XMLHttpRequest.setRequestHeader(), and hence must be triggered by same-origin content, as opposed to a random third-party site. This provides a coarse cross-site request forgery defense, although the mechanism may be potentially subverted by the incompatible same-origin logic within some plugin-based programming languages, as discussed later on.

But David Chandler is right in saying it doesn't offer complete protection against CSRF. It works today; but it was an issue in the past, and it may become an issue in the future. If you have users from the past (i.e. using old plugins/browsers), this solution isn't for you.

--Sri



--

Philippe Beaudoin

unread,
Dec 1, 2010, 2:49:17 PM12/1/10
to google-we...@googlegroups.com
On Wed, Dec 1, 2010 at 11:30 AM, Sripathi Krishnan
<sripathi...@gmail.com> wrote:
>> This is really interesting and I was not aware of that feature of modern
>> browsers. Could you clarify how this works or link to a website explaining
>> it? (In particular, I'm interested to know how a browser can prevent
>> malicious javascript to insert this header in a request.)
>
> Here are some discussions on this topic -
>
> http://www.webappsec.org/lists/websecurity/archive/2010-09/msg00099.html
> http://michael-coates.blogspot.com/2010/05/csrf-attacks-and-forged-headers.html
> http://stackoverflow.com/questions/2609834/gwt-rpc-does-it-do-enough-to-protect-against-csrf
>
> Also, see browser security guide. I quote -
>>
>> Please note that the degree of flexibility offered by XMLHttpRequest, and
>> not seen in other cross-domain content referencing schemes, may be actually
>> used as a simple security mechanism: a check for a custom HTTP header may be
>> carried out on server side to confirm that a cookie-authenticated request
>> comes from JavaScript code that invoked XMLHttpRequest.setRequestHeader(),
>> and hence must be triggered by same-origin content, as opposed to a random
>> third-party site. This provides a coarse cross-site request forgery defense,
>> although the mechanism may be potentially subverted by the incompatible
>> same-origin logic within some plugin-based programming languages, as
>> discussed later on.

Thanks for these links and explanation, really useful! So, to
summarize my understanding:
- Requests issued by forms do not allow you to add custom headers
- Javascript (XMLHttpRequest) cannot be used in an XSRF attack due to
same-origin-policy
- Therefore, if you exclude mechanisms based on faulty plugins (or old
browsers), there is no way for a 3rd party webpage to ping your webapp
while including custom headers.

As a result, if you assume:
1) Your user is running a modern browser
2) Your user doesn't have a faulty plugin

Then, the presence of a custom header is enough to guarantee that the
request was created with javascript and this originate from your page.

Did I get this right?

Philippe

Sripathi Krishnan

unread,
Dec 1, 2010, 2:57:32 PM12/1/10
to google-we...@googlegroups.com
Thanks for these links and explanation, really useful! So, to
summarize my understanding:
- Requests issued by forms do not allow you to add custom headers
- Javascript (XMLHttpRequest) cannot be used in an XSRF attack due to
same-origin-policy
- Therefore, if you exclude mechanisms based on faulty plugins (or old
browsers), there is no way for a 3rd party webpage to ping your webapp
while including custom headers.

As a result, if you assume:
1) Your user is running a modern browser
2) Your user doesn't have a faulty plugin

Then, the presence of a custom header is enough to guarantee that the
request was created with javascript and this originate from your page.

Did I get this right?

Yes, that's a good summary. 

--Sri

Sergei Kirsanov

unread,
Jul 26, 2013, 5:53:18 AM7/26/13
to google-we...@googlegroups.com
What's the current state of Request Factory and CSRF/XSRF for 2.5.1 version? This post confuses me: http://stackoverflow.com/questions/6227436/preventing-csrf-when-using-gwts-requestfactory

Thomas Broyer

unread,
Jul 26, 2013, 9:05:25 AM7/26/13
to google-we...@googlegroups.com


On Friday, July 26, 2013 11:53:18 AM UTC+2, Sergei Kirsanov wrote:
What's the current state of Request Factory and CSRF/XSRF for 2.5.1 version?

Nothing's changed.
What confuses you?

BTW, wrt what's written above about the presence of custom headers being enough (which I'm not sure about, but I'm not a security expert), the DefaultRequestTransport includes two such headersalready, so it's mostly a matter of checking their presence on the server-side:

Sergei Kirsanov

unread,
Jul 26, 2013, 9:17:36 AM7/26/13
to google-we...@googlegroups.com
I was confused by the fact, that the post was written later than a solution was suggested here, but X-GWT-Permutation was not mentioned there. Anyway, thanks Thomas.
Reply all
Reply to author
Forward
0 new messages