Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I have a static site which has forms. The forms submit to a Rails endpoint which captures the submitted data. The static site and the Rails endpoint are on the same domain, on different subdomains and all traffic is completely on HTTPS.

I understand how Rails CSRF works for server generated forms. But in my case, these forms are on static HTML pages. I understand all request headers can be faked, so can't rely on that.

If a strong solution is not possible for this scenario then my last option would be to move to server generated forms (which I want to avoid for now).

Any suggestions on a good approach to this would be most welcome. Or any pointers to a system or a library which already does this.

I could implement a REFERER check on the HTTPS POST request (in my case) - is that enough ? Can that not be spoofed ?

The CSRF prevention cheat cheat sheet says: Although it is trivial to spoof the referer header on your own browser, it is impossible to do so in a CSRF attack. - I don't quite understand this.

Any help would be much appreciated.

share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted

I can make any request to your server, with any headers and values that I want. So an attacker can very easily send you a packet with a referrer that's picked by him. But how'd you go about this in a CSRF attack?

CSRF works by me sending you to a webpage that I control, and then that webpage redirects your browser to the webpage to execute the CSRF. For example I could send you (via that attack page) to https://example.com/usermgmt.php?action=delete&user=1, which might make you inadvertently delete userid 1.

What your browser does is set the REFERER header (when loading usermgmt.php) to whereever it came from, for example http://malicious.tld. If usermgmt.php checked the referer, it would notice that it didn't come from the same domain. Thus you can't (by default) spoof referers for CSRF.

One catch here are things like login pages. Consider this: https://example.com/login.php?returnTo=index.php. A CSRF attack only works when the victim is logged in already, else the attacker could just load the URL himself. And if you are logged in, the login page probably just redirects you to the return URL directly. Now what if you write usermgmt.php?action=delete&userid=1 as the return URL? It will redirect from login.php to usermgmt.php, and the referer received by usermgmt.php will be https://example.com/login.php?returnto=x. It seems totally legit, but it's not.

Also, some browsers may not include a referrer for privacy reasons, which would then break the website. I don't know of any browsers having this option ("feature"?) without installing a special add-on, but you never know.

So the best solution is to use CSRF tokens, and I certainly would if you are going to host something for a bigger audience, but if it's for a closed usergroup you're probably okay checking the referrer.

share|improve this answer
1  
Also note that the redirection attack only works with GET. –  Rook Oct 29 '12 at 20:49
add comment

Personally, I do not recommend using the Referer header to stop CSRF attacks. It has two issues:

  • First, it is fragile. There is a long past history of attacks on the Referer header, involving (variously) exploits on plugins (e.g., Flash), bugs in browser APIs (e.g., XHR), and redirection. To be clear, I'm not saying that checking the Referer will necessarily be insecure; I'm just arguing that I think it's more fragile, and I would have more confidence in a solution that uses CSRF tokens.

  • Second, some browsers and corporate firewalls block the Referer header for privacy reasons, meaning that you'll be forced to block legitimate users. So the Referer header is simply not a good solution.

Instead of using the Referer header, I would recommend that you use CSRF tokens.

share|improve this answer
    
-1 if you are so sure that an attack exists you should write an exploit for it. There is already too much misinformation in security, we need real PoC's to prove that a system is insecure. –  Rook Oct 29 '12 at 19:23
1  
I don't need to write an exploit; others already have. There's a long history of such attacks. The known attacks might not work on a fully patched modern browser today, depending upon how the Referer header is used, but I would not have any confidence that there are no other attacks, and I would not have confidence that people using older browsers are adequately protected. If you want detailed evidence for these claims, ask a separate question about the history of attacks on the Referer header, and I'll be happy to oblige. That is beyond the scope of this question. –  D.W. Oct 29 '12 at 19:39
    
There have been more SOP bypass exploits that could be used to read a CSRF token than there have been CRLF injection attacks to bypass the referer. There have been more remote code execution exploits written then all of these combined and if you are vulnerable to a CRFL injection on the client side you would also be vulnerable to remote code exectuion. If you can't write a PoC, then you have no business saying its insecure. –  Rook Oct 29 '12 at 20:51
1  
@Rook, A small correction: I didn't say it is insecure. I'm saying it is "very fragile", which is a bit different. (Let me re-express in different words, in case my answer was not clear: I would have more confidence in a defense based upon CSRF tokens than a defense based upon the Referer header.) –  D.W. Oct 29 '12 at 22:14
    
That is something I can't disagree with. –  Rook Oct 29 '12 at 23:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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