Being inspired from a class that I took on computer security and being particularly moved by literature written on Cross-Site Request Forgery, namely a paper written by Zeller et al. [1] I decided to begin work on a Chrome extension that would locally aid in the prevention of CSRF attacks by stripping cookies from potentially dangerous requests.
The Princeton paper mentions that this can be done if the following two rules are implemented:
- Allow any GET request to go through, since HTTP/1.1 dictates that GET requests should not perform action.
- Block (strip cookies) any non-GET request which voids the same-origin policy.
I went ahead and did just that in the development of No-CSRF, which shamelessly used a very similar extension by avlidienbrunn as a starting point.
After about a week of testing the extension through myself and some colleagues, we discovered that this method of preventing CSRF actually broke many websites, including (but not limited to) Google Drive, Facebook Messenger, and a login page for the University of California, San Diego.
The reasoning for this breakage was simple. These websites relied on functionality that sent cross-origin non-GET requests to different parts of product, each with their own sub-domain. The sub-domain, of course, is included in an origin and therefore differing sub-domains indicate different origin.
One thing to note is that the paper by Zeller et al. suggested that the stripping of cookies should not be performed if the request is valid under Adobe’s cross-domain policy. However, even when allowing the websites outlined in crossdomain.xml, functionality was still broken.
There are a few results that follow from these observations:
- The local CSRF protection scheme outlined in Zeller et al. cannot be accomplished without breaking several popular websites.
- In order to resolve this, the policy may be changed such that cookies are only stripped from requests that are cross-domain, where a domain is defined as everything not including the sub-domains (for instance, the domain of drive.google.com would be google.com. Thus, a non-get cross-domain request from calendar.google.com to drive.google.com would not be stripped.)
- On a shared system where different users control different sub-domains, therefore, it is possible for attacker.website.com to send a malicious CSRF attack to private.website.com without stripped headers.
In fact, this proposed lax “cross-domain stripping” is exactly what was implemented in avlidienbrunn’s extension before I removed it and replaced it with a stricter “cross-origin stripping” in No-CSRF.
As a result, therefore, I propose that by sending cross-origin non-GET requests, major websites are limiting the success of local CSRF prevention by forcing them to be less-strict about which requests have their cookies stripped.
↑1 | Cross Site Request Forgeries: Exploitation and Prevention. Zeller, William and Felten, Edward W. Princeton University, 2008. |
---|