3

We're building an app with a Java Spring/Hibernate backend running in JBoss. The frontend is AngularJS.

We haven't yet done anything to setup XSRF tokens on the server end. We also don't (not yet anyway) have a requirement to allow other domains access to our web resources.

I figured I'd try to see if our site was vulnerable to an XSRF attack so I set up a malicious webapp to post to one of our real app's urls using Angular's $http.post(). I logged in to the real app, then I tried posting from the malicious app.

In the browser I got a 401 response and saw the error:

XMLHttpRequest cannot load http://localhost:8080/user/delete. No
'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:6543' is therefore not allowed access. The response
had HTTP status code 401.

The server side isn't setup to set Access-Control-Allow-Origin on the response thus the above error.

So my question is, is simply omitting Access-Control-Allow-Origin from the response header adequate to prevent XSRF attacks?

Is there a way I could still do an XSRF attack on my site even though Access-Control-Allow-Origin is not set? If so how? I'd like to demo this attack.

Thanks.

lostdorje
  • 5,370
  • 7
  • 39
  • 80

1 Answers1

5

No, this is not sufficient. Even though the browser gives the 'Access-Control-Allow-Origin' error, the request has still been made by the browser. If withCredentials is specified by the attacking page:

$http.post(url, {withCredentials: true, ...})

then this request will be sent to your domain with the victim's authentication cookies, meaning that the request to http://www.example.com:8080/user/delete will succeed.

Also, this request could also be made without XHR using a standard HTML form:

<form method="post" action="http://www.example.com:8080/user/delete">

and JavaScript would just be used to submit the form rather than making the request itself.

An easy way to protect your system against CSRF is to check for a custom header such as X-Requested-With or the Origin header. X-Requested-With cannot be sent cross domain without enabling CORS server-side. However, the Synchronizer Token Pattern is still the strongest method of CSRF prevention as this is not subject to flaws in browser plug-ins such as a previous flaw in Flash that allowed headers to be sent that weren't normally possible from a browser.

Community
  • 1
  • 1
SilverlightFox
  • 28,804
  • 10
  • 63
  • 132
  • I may have spoken too soon. Setting 'withCredentials' to true had no effect. I also tinkered with $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest' in combination with the 'withCredentials' and I couldn't come up with a variation that made the request succeed. – lostdorje Oct 24 '14 at 02:37
  • @lostdorje: Make sure that you have 3rd party cookies enabled in the browser and you can verify that cookies are being sent using an intercepting proxy (some dev tools don't actually show the cookies because of the Same Origin Policy). I [answered a very similar question the other day](http://security.stackexchange.com/a/71082/8340), however this was from the attacker's perspective. – SilverlightFox Oct 24 '14 at 09:48