1

At work we suspect a GWT app (that is not in production yet) we own to be vulnerable to CSRF. We have to look at it from a black-box point of view before a third-party security audit will be performed.

Due to the fact that all calls in the app are made through AJAX (with method POST), simply replicating an Ajax call in a malicious way is not achievable thanks to the Same-Origin policy. In fact we know that there is no csrf protection, but since only the request bodies ("payload" in the network tab of Chrome) are read by the server, it feels at first glance that the vulnerability cannot be exploited.

Is there a way to forge a similar request through a browser with a classic form ? My problem is that I cannot replicate the body of the Ajax call through a form : the app reads the body of the requests - submitting a classing form requires inputs with key/value pairs which would not be taken into account by the server.

In other words, is it possible, with an html form, to submit a request that just contains text in a body, instead of key-value pairs in the body ? Or is there another attack angle for such cases ?

Edit (additional info):

The clicks on buttons of the application generate requests that use text/x-gwt-rpc; charset=UTF-8 as content-type which, I suppose, is what gwt RPC call handlers expect, and cannot be "forged" with a normal browser (of course such a request could be forged without a browser, but that is OK, since I'm just trying to exploit a potential CSRF).

What notably bothers me is the fact that I know that there are no CSRF tokens in the requests, and that there could exist a tricky way to forge the malicious requests - but I don't see how.

2

Your application uses AJAX posts with the content type set to text/x-gwt-rpc.

In other words, is it possible, with an html form, to submit a request that just contains text in a body, instead of key-value pairs in the body ?

According to the HTML specification, it is only possible to set the following content types for an HTML form:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Therefore it is not possible to set it as text/x-gwt-rpc and have it understood by the browser.

This denotes the "GWT-RPC Wire Protocol". With some content types, it might be possible to "trick" the browser into sending another type of payload by using text/plain. For example, here is how it could be done with a JSON payload, although it will be sent without the correct content-type header.

<form enctype="text/plain" method="post">

<input type="hidden" name="{&quot;foo&quot;: &quot;bar&quot; }//" value="" />

<input type="submit" />

</form>

would be sent as

{"foo": "bar" }//=

Not perfect, but you get the idea.

Or is there another attack angle for such cases ?

If your application is not checking the content type of the submitted form server side, it might be possible for an attacker to construct an AJAX request and POST that cross-domain to your server. For example, they may set the content type to be text/plain, which is allowed cross domain without an OPTIONS request.

The allowed cross-domain content types for AJAX request exactly matches the content types allowed via an HTML form.

An option for you could be to add a header to your requests such as X-Requested-With and then verify this server side. As this header cannot be included in a cross domain request without the server opting in via CORS, this will protect your application against CSRF attacks.

  • Thanks for your valuable answer. Actually, the content-type used by the app is "text/x-gwt-rpc; charset=UTF-8" The body of the requests is just a succession of values separated by the "|" character. Given the fact that GWT most probably checks for the content-type, and that classic browsers won't send such content-types through a <form> submission, I suppose that the vulnerability is not exploitable in this particular context. – niilzon Mar 27 '15 at 12:48
2

With a normal CSRF attack, only Simple Requests are vulnerable. Those docs detail the requirements for a "simple request", but a request that uses content-type of "text/x-gwt-rpc" is not a simple request.

Although traditional CSRF attacks can only exploit simple requests, you can use Flash to exploit "complicated requests". The attack is more complicated, and requires that a user enable flash on the attackers website, but it is still a viable attack method. The json-flash-csrf-poc repository has an example attack that you can run yourself locally and adapt to your own server if you want to test it. Additionally, check out their blog for a deeper explanation of how it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.