20

I am well aware of the concept of CSRF, and I think I am also aware of the possible protection possibilities, as described by OWASP. However, I'm not sure why the synchronizer pattern seems to be preferred, if we could just as easily check the origin header of the request. The latter could be done server-wide, which would make it much easier to implement than the synchronizer token pattern. The only downside to me is that no POSTs from a different domain could be made then, but even then we could foresee some white-list filter.

What are other reasons to prefer the synchronizer token pattern over the origin header check?

Michael
  • 5,393
  • 2
  • 32
  • 57
  • 2
    There is another approach to CSRF: http://security.stackexchange.com/questions/23371/csrf-protection-with-custom-headers-and-without-validating-token – paj28 Jun 10 '15 at 15:04

3 Answers3

16

Simply put

This would make for complex logic when implementing CSRF protection.

That is:

Lack of Origin header = Old browser/bug OR
Lack of Origin header = Same Origin
Origin header matches domain = Same Origin
Origin header does not match = CSRF attack

As you can see, it is not possible to distinguish between old or buggy browsers possibly making CSRF attacks and legitimate current browser requests. You could add browser detection, but then the logic gets more messy. Complexity tends to reduce security.

This of course, could be patched in a browser update. However, then your application would be incompatible with older versions of the browser.

Much simpler would be to generate a token and send that with each request outside of the cookie mechanism.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • On the other hand, for an *existing application*, the CSRF token way is *backward-incompatible*: all the clients would have to be updated, or they will instantly break the moment the server starts blocking the requests without token. It might be a stopper for certain scenarios (or, one could do a gradual roll-out: first implement the token exchange between the server and clients, but not enforce token validation on server only after high enough percentage of clients have been updated). By clients, I mean clients of the API; for instance, hybrid mobile apps. – jakub.g Sep 28 '15 at 07:32
  • 1
    Does it make sense, when it comes to web security, to consider that "browser can be old"? Non-last-version of browsers should be discarded from security plans. In other words, if we don't consider "old browser" as an issue (it's user/client's responsibility), then is there a reason to not use `HTTP: Origin` as anti-CSRF mechanism? – Xenos Sep 26 '18 at 08:14
  • @Xenos That is a good point. However, at the time of writing there exists bugs in current implementation of the origin header in that e.g. Firefox does not send this header with POST requests. My answer updated. – SilverlightFox Oct 26 '18 at 11:48
  • @SilverlightFox It's still irrelevant IMO since the bug is actually fixed, and even if it's not, then it's a *browser* bug, so you must fix it in the browser, not in every single web application. – Xenos Oct 26 '18 at 13:30
  • @Xenos I don't think it is irrelevant because this makes it impossible to have an application that is secure against CSRF, _even at this moment in time_. Why wait for some future bug fix in a browser when you can secure your application _now_? For now use tokens until this is fixed. – SilverlightFox Oct 26 '18 at 15:15
  • I believe the bug has been fixed in FF. If you don't care about old browsers, the Origin header can actually be an adequate defence. Of course, this also depends on the server performing the correct checks, and that your server's API is designed well, e.g. don't allow state-changing requests using GET. – light Jun 04 '19 at 10:43
6

It's mostly due to history. People have been aware of CSRF since the early 2000's, before the Origin header had been invented. The concept of "token in a hidden field" provided sites an immediate way to fix the flaw, without waiting for browsers to update. While the mechanism is a little messy, it turns out it is possible for frameworks to provide this functionality automatically, with little input from application developers. Notably, .Net included this from the start with EVENTVALIDATION/VIEWSTATE, and it is relatively rare for .Net applications to have CSRF flaws.

When CSRF was first taken seriously, some people proposed checking the Referer header to fix the flaw. It is widely known that the Referer header is easy to spoof, but this idea is not as silly as it seems. When an attacker makes a direct connection to a web server, it is easy to spoof the Referer header. However, in a CSRF attack, the attacker is not making a direct connection; the victim's web browser is making the connection, and the attacker cannot readily control the Referer header. However, this approach turns out still to be flawed. Older versions of Flash allowed an attacker free control of the Referer header in a CSRF attack scenario. Also, some users disable the Referer header for privacy reasons, which a web site would mistake for a CSRF attack.

The Origin header has been developed as a more secure replacement for the Referer header. In many ways, it is a much neater solution to CSRF, and it avoids the overhead of managing the tokens. Some applications - particularly single page applications - use the Origin header as the only CSRF protection and are completely secure. However, this is the exception rather than the rule. The synchroniser pattern is well understood, widely supported by frameworks, and has no known weaknesses.

Edit - Silverlightfox informs me that the following is not true. See his answer for more info.

Ultimately I think OWASP are being a little backward in their advice. In 2015 they should be advising Origin header checks as the primary control, with the synchroniser pattern as a legacy alternative.

paj28
  • 32,736
  • 8
  • 92
  • 130
  • 3
    Note that [some browsers don't send the `Origin` header for same origin requests](http://stackoverflow.com/a/15514049/413180). This will make the logic cumbersome and you won't have any protection against CSRF for pre-CORS browsers. Also, `__EVENTVALIDATION` is not a CSRF prevention measure - it is a way of validating page state before triggering an event. `__VIEWSTATE` could be considered CSRF prevention, but only if it is encrypted with a session specific value (e.g. the actual Session ID). – SilverlightFox Jun 09 '15 at 12:38
  • @SilverlightFox - Thanks... wasn't aware of that issue with same origin requests. Sounds like that makes the Origin checking approach pretty much invalid - perhaps you should post your own answer to the question to expand on that. BTW, you may be right about VIEWSTATE/EVENTVALIDATION, but that's going a bit on a tangent; I've edited my answer to speak about .Net more generally. – paj28 Jun 09 '15 at 13:10
0

Any browser flaw for example where it allows Origin header being set client-side(highly unlikely with modern day browsers) will now enable CSRF attacks against your application.

Additionally, from https://security.stackexchange.com/a/74526/66075

You can't currently depend on the Origin header, because it is not implemented in all browsers which are in active use. Apart from that, Origin is not sent in all cases relevant to CSRF.

Also, from SilverlightFox's answer to a similar question at https://stackoverflow.com/a/24692474/4399898,

There have been previous browser vulnerabilities such as those in IE 5.5/6.0 where it has been possible for attackers to bypass the Same Origin Policy and execute attacks. You can typically expect these to be patched as soon as discovered and with most browsers automatically updating, this risk will be mostly mitigated.

and

Old versions of Flash allowed arbitrary headers to be set which would enable an attacker to send a request with a spoofed referer header from the victim's machine in order to execute an attack.

racec0ndition
  • 581
  • 4
  • 10
  • Any XSS flaw on the external domain would allow the synchronizer token pattern to work too (and most other mechanisms except for CSRF protection via reauthentication). XSS almost always trumps CSRF - you've already lost if there's an XSS flaw (usually). – SilverlightFox Jun 09 '15 at 11:26
  • @SilverlightFox Are you saying, any XSS flaw on the ext. domain would allow forging the token? – racec0ndition Jun 09 '15 at 11:43
  • 1
    Well, yes. If you are allowing another domain to POST to yours, you must allow them access via some means, although likely via `Access-Control-Allow-Origin` so that the domain can read the CSRF token. If an attacker has control of the external domain they can modify any forms or AJAX scripts to POST data of the attacker's choosing whichever way they work. – SilverlightFox Jun 09 '15 at 12:07
  • @SilverlightFox I got your point, edited. Thank you again. – racec0ndition Jun 09 '15 at 12:07
  • Ha - sorry. I know that I picked a hole in another post you made yesterday. ;) – SilverlightFox Jun 09 '15 at 12:07
  • @SilverlightFox ha yah :p But your contributions are most welcome. My posts lately have been rusty and under-thought. – racec0ndition Jun 09 '15 at 12:11