5

CSRF tokens are used a lot.

The server sets a token in cookie for that domain that either (1) include in the HTML form or (2) Javascript can read and include in the request. The server verifies the token in the request matches the token in the cookie.


But why not simply check the Origin header? According to OWASP, that's why it exists:

The Origin HTTP Header standard was introduced as a method of defending against CSRF and other Cross-Domain attacks.

"Is the Origin not there? If not, OK. If it is, is it one one I trust (e.g. the same origin)? If so, OK."


CSRF tokens can be troublesome. They are

  • more difficult for beginners to understand -- "Wait...I send it twice? What's CRSF again?"
  • requires cookies (granted, not usually a problem)
  • more difficult to implement -- needs controller and view
  • less flexible -- can't ever work cross-domain
  • strange in non-web settings -- "Why does your API need a CSRF token?" "Oh, 'cause JS uses that too."
  • more cumbersome to implement globally -- "Oops, forgot the CSRF tag here among my 25 HTML form fields"

Given these disadvantages, why are CSRF tokens so commonly used, rather than the Origin header?

2
  • 1
    stackoverflow.com/questions/24680302/… Here is a similar question.
    – sir_k
    Dec 8, 2014 at 9:15
  • CSRF tokens are the best method to prevent CSRF vulnerabilities. There are other checks that help with prevention like the origin header, different types of challenges, and checking the referrer header. While these methods can help with prevention, none of them are as effective as tokens. Dec 8, 2014 at 13:56

2 Answers 2

6

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, like

<img src=http://router/admin.cgi?...>
7
  • @PaulDraper: just tested with latest Chrome and Firefox. Both don't sent an Origin header if including an image from a remote site. But this is a typical vector for CSRF. Dec 8, 2014 at 13:34
  • Hm....it would seem inappropriate then for OWASP to recommend it, right? "This section details other ways that an application can prevent CSRF by relying upon similar rules that CSRF exploits can never break...Checking The Origin Header". Dec 8, 2014 at 14:04
  • 2
    @PaulDraper: it does not say that you can rely on the Origin header to exist, only "If the origin header is present, then it should be checked for consistency." Dec 8, 2014 at 14:08
  • 1
    @PaulDraper Strictly speaking, I think if you treat a lack of origin as a failed origin-match, a CSRF attack can't break your security, but your website may still break (i.e., fail to function normally for browsers that never send Origin headers) without an attack. An attack doesn't break your site; the browser's failure to send an Origin header breaks your site. That's obviously not great site design, but that's only reading of "rules that CSRF exploits can never break" I can think of that is strictly correct.
    – apsillers
    Dec 8, 2014 at 14:08
  • 2
    Since GET is a safe operation (as defined the HTTP standard), I suppose checking the Origin header would be sufficient for preventing non-safe operations from any modern browser to a standards-compliant server. That is sufficient in my case. Jan 30, 2015 at 1:08
0

"Is the Origin not there? If not, OK. If it is, is it one one I trust (e.g. the same origin)? If so, OK."

Although you can use the Origin header to reject a request. If the Origin header is missing, you cannot safely accept it, even for POST requests. As far as I know, an HTML form request doesn't include an Origin header, and neither do imgs, scripts, links, cos background images, or other places that make get requests. And of course the Origin header isn't sent for XHR requests on the same host, so you need another protection mechanism.

One option is to put the csrf token in a custom header, which is easier to do globally and doesn't put the token in the URL for get requests. And then if desired you can check that the request either has the Origin header or custom header.

You might also be able to do something like the method you mentioned, provided you reject any request that isn't an Ajax request. But I am not as confident about the security of that.

In short the Origin header, by itself isn't enough if you want to make same-origin requests, but could be used in combination with another csrf protection method.

5
  • It would seem that for form POSTs, some browsers include the Origin header, but others do not. It does seem incongruous with OWASP: "This section details other ways that an application can prevent CSRF by relying upon similar rules that CSRF exploits can never break." Jul 29, 2015 at 14:33
  • And if it is not present? Jul 29, 2015 at 14:40
  • "If the origin header is present, then it should be checked for consistency." OWASP doesn't say it is safe to accept requests without an Origin header, merely that if the header is present it can't be broken by CSRF. The section on using the referrer header states that if it is missing it must be rejected
    – Thayne
    Jul 29, 2015 at 14:43
  • There is the potential for vulnerability if even one browser doesn't send the header.
    – Thayne
    Jul 29, 2015 at 14:44
  • 1
    Yeah, it certainly does seem like a subpar recommendation. Jul 29, 2015 at 17:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .