7

Imagine a generic web application with a login form to access the application. Regardless of how the actual authentication is performed, what are the implications of not checking the referer header to verify the submit request is coming from within the same application/domain/approved URLs?

Another way to think about this is if you drop the referer header check and are checking something that verifies its coming from a known source. What are the implications of not checking the form data source?

Specifically in a passive scenario, e.g. purely browser based.

The biggest implication I see is that I can submit the credentials from another site and log in successfully.

But what risks are there in this? I realize it depends on each application and the threat models for it, but can this be generalized?

3 Answers 3

7

A CSRF attack tries to exploit "the trust that a site has in a user's browser" (so says the Wikipedia page, and it is well said). It is about the server accepting a request from the client, on virtue of the request coming with some authentication characteristic which makes the server believe that it comes from the genuine user (which it does) and under the conscious control of the genuine user (which is false). The "authentication characteristic" would classically be a cookie value (acceptable for the server), or HTTPS with certificate-based client authentication.

For a login page, the server does not trust the request from the client. That's the point of a login page: to initialize trust. The login page expects a login and a password precisely because there won't be anything that the request can come with, which will make the server happier and distract it from its intended action, which is to verify the login+password pair. As such, CSRF attacks don't apply to this page.

You can still check the Referer field to check for "fishy business" (if it is absent or wrong, then something is definitely amiss), but it won't really change the security.

1
  • "if it is absent or wrong, then something is definitely amiss" -- Yeah, like the user directly bookmarking the page. Or disabling Referer headers to reduce tracking. Or their browser autocorrects Referer to Referrer, because only the latter is a word, and the former is a typo...
    – anon
    Commented Jul 11, 2019 at 20:25
6

What is the implication of verifying it? The referer header:

  • can be spoofed by the client
  • can be completely omitted by the client (notoriously when going through TOR/proxies)
  • is no guarantee that the user actually came from there

There referer header is sent as a courtesy from your browser, it is not a HTTP RFC requirement. See here for details on the header: http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html#z14 .

It should be therefore obvious that this header holds no value whatsoever, and should not be a guarantee of anything. In addition, anyone smart enough can spoof this. If you want real guarantee that your log-in form data did come from your log-in form, build a check that attempts to find a unique, randomly-generated, user-based (or navigator-based) value. This will be a lot more reliable (but, depending on the implementation, not necessarily bullet-proof) than a Referer header.

5
  • The referer header protects against client stupidity though. It applies to the wider audience of people who don't know about csrf. Commented Apr 17, 2013 at 19:10
  • Well yes, okay. Let me update my question to narrow the focus a bit.
    – Steve
    Commented Apr 17, 2013 at 19:11
  • 2
    @Manishearth: I don't know. Personally, if I had a choice between a silver bullet and a dodgy-at-best referrer (with false positives and negatives), I'd personally pick the CSRF token. Hide it (input[type="hidden"]) in the form, and you're sure that it will go through on selected forms. Commented Apr 17, 2013 at 19:12
  • @SébastienRenauld: Of course. I'm just saying that it isn't entirely useless. Commented Apr 17, 2013 at 19:17
  • 1
    Its only utility is statistics and possibly post-attack forensics. I hope we agree on this :-) Commented Apr 17, 2013 at 19:25
2

For a login form -- not so much. The most that could happen is a well-known site like Facebook could go rogue and use their clients' machines (via POST requests from an embedded form triggered by javascript) as part of a botnet-like entity to bruteforce your login form.

But that's rather unlikely, so there's no problem with not checking referers on login.

Note that the rest of the website, after login, should check referers on any sort of request (GET or POST) with side effects. Otherwise, I could create a site which has an embedded iframe with contents like:

<form method=post action="www.yoursite.com/makepayment.php">
<input type=hidden name="to" value="123453323">
<input type=hidden name="amount" value="$10000">
</form>

and JS-trigger the form, submitting a POST request that transfers money from you to me (or whatever).

You want to avoid that, so check referers there.

Even better, use a CSRF token (a temporary token that is attached to a specific account for a small period of time) in an <input type=hidden> on every form on the page that has side effects (i.e., does not simply load a new page but also mutates the data stored on the server or elsewhere)

3
  • CSRF tokens are the only way to go. HTTP headers including Referer are trivial to spoof, and may be dropped by browsers for privacy reasons.
    – dr jimbob
    Commented Apr 17, 2013 at 19:43
  • Is it really true that all requests should use CSRF tokens? I thought the utility of CSRF tokens was in safeguarding requests which have side-effects. If we're writing well-behaved web applications, GET requests would not fall into this category. Commented May 19, 2014 at 22:50
  • 1
    @DavidSanders Good point, changing Commented May 20, 2014 at 4:10

You must log in to answer this question.

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