Is checking the referrer enough to protect against a CSRF attack?
Asked Answered
S

6

51

Is checking the referrer enough to protect against a cross site request forgery attack? I know the referrer can be spoofed, but is there any way for the attacker to do that FOR the client? I know tokens are the norm, but would this work?

Saurel answered 12/9, 2009 at 1:10 Comment(2)
You should include your programming language/platform, as many (e.g. ASP.NET MVC's AntiForgeryToken) out-of-the-box solutions exist.Pteridology
Same question on Security.SEEpidote
M
11

Among other things, using the referrer won't work for users whose browsers (or corporate proxies) don't send referrers.

Menard answered 12/9, 2009 at 1:16 Comment(4)
Cheekysoft: It is true that Referrers can be easily faked, but that isn't why you shouldn't use them for CSRF protection. Attackers that are in a position to perform a CSRF attack are not in a position to fake Referer headers.Menard
you could also check ORIGIN header - see people.mozilla.org/~bsterne/content-security-policy/… Google Chrome implements sending this header, so it is always appears in POST requestsMatrass
@Duro How can an attacker fake the referrer header in a modern browser?Branscum
@Branscum My comment was from nearly 10 years ago and whilst true, even back then it probably needed to abuse browser plugins in a CSRF-only context. It certainly would have been easy from a malicous Flash app (crossdomain.xml depending) or a Java applet, in 2009 . See the answer below from Aleksander Blomskøld for a more focussed understanding, considering the more locked-down modern browser.Duro
A
52

This is a 3 year old question with four different answers basically stating the same thing: Follow the norm, use tokens, don't try to use referer.

While tokens still is considered the most secure option, using the referer is often a lot easier, and is also pretty secure. Just be sure to look at all PUT/POST/PATCH/DELETE-requests and consider it an attack if a referer is missing or from the wrong domain. Really few (if any) proxies remove the referer for these kinds of requests.

See also the OWASP recommendation about checking the referer header as a CSRF protection:

Checking The Referer Header

Although it is trivial to spoof the referer header on your own browser, it is impossible to do so in a CSRF attack. Checking the referer is a commonly used method of preventing CSRF on embedded network devices because it does not require a per-user state. This makes a referer a useful method of CSRF prevention when memory is scarce.

However, checking the referer is considered to be a weaker from of CSRF protection. For example, open redirect vulnerabilities can be used to exploit GET-based requests that are protected with a referer check. It should be noted that GET requests should never incur a state change as this is a violation of the HTTP specification.

There are also common implementation mistakes with referer checks. For example if the CSRF attack originates from an HTTPS domain then the referer will be omitted. In this case the lack of a referer should be considered to be an attack when the request is performing a state change. Also note that the attacker has limited influence over the referer. For example, if the victim's domain is "site.com" then an attacker have the CSRF exploit originate from "site.com.attacker.com" which may fool a broken referer check implementation. XSS can be used to bypass a referer check.

Armillda answered 4/1, 2013 at 7:43 Comment(3)
The question asks "Is checking the referrer enough [...]?". My reading of the OWASP guidelines is that the answer is "no, it's not enough". It's only useful as part of an overall strategy. It also depends on whether the checks are loose (allowing a blank header) or strict (failing a blank header). Strict checks are more useful from a protection perspective but will cause issues with proxies (as mentioned elsewhere). The proportion of users with the referrer header stripped may be low on the general web, but if you're dealing with enterprises tread with caution, measure, and ask your user base.Oca
Also take into account, that Referrer Policy (developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…) allows to unset Referer header, that can lead to the following vulnerability sjoerdlangkemper.nl/2017/06/21/…Ubiquitous
Why do you need to check referrer for PUT/DELETE? Aren't these requests protected by same-origin-policy?Cricoid
M
11

Among other things, using the referrer won't work for users whose browsers (or corporate proxies) don't send referrers.

Menard answered 12/9, 2009 at 1:16 Comment(4)
Cheekysoft: It is true that Referrers can be easily faked, but that isn't why you shouldn't use them for CSRF protection. Attackers that are in a position to perform a CSRF attack are not in a position to fake Referer headers.Menard
you could also check ORIGIN header - see people.mozilla.org/~bsterne/content-security-policy/… Google Chrome implements sending this header, so it is always appears in POST requestsMatrass
@Duro How can an attacker fake the referrer header in a modern browser?Branscum
@Branscum My comment was from nearly 10 years ago and whilst true, even back then it probably needed to abuse browser plugins in a CSRF-only context. It certainly would have been easy from a malicous Flash app (crossdomain.xml depending) or a Java applet, in 2009 . See the answer below from Aleksander Blomskøld for a more focussed understanding, considering the more locked-down modern browser.Duro
D
9

The only correct answer is "Among other things, using the referrer won't work for users whose browsers (or corporate proxies) don't send referrers." That being said, that's highly uncommon nowadays. All the people saying that referrers can be faked are full of it. You cannot fake a referrer unless you have control over the other person's browser in some other way (XSS/Trojan/etc). If you require referrers for app use they are just as effective as CSRF Tokens. Just make sure you are making 100% sure that your check is correct (eg. if you are using regex make sure you check from the beginning "^" of the referrer).

Dayflower answered 7/2, 2013 at 15:4 Comment(9)
Attacker can create his own brand new browser. Browser is just software that anyone can write. For all we know hackers might have some special browser letting them change the referer at will in the configuration.Burck
@ShadowWizard: Isn't CSRF a means to trick another browser (person) to do something with his logged in account on the primary website? What browser the hacker uses is of no importance.Coniine
@Coniine I was referring to the first part of the answer especially to "All the people saying that referrers can be faked are full of it". Referrer CAN be faked and the way to fake it is by using a "fake" browser that send the server whatever it want to.Burck
@ShadWizard My statement was in reference to CSRF prevention. Your statement is not.Dayflower
@ShadowWizard: If the attacker has given the user a malicious browser, then CSRF are the least of his worries.Fidellia
@joey I mean attacker using his own browser to perform the attack as a user of a site counting on referrer for its protection. The attacker is the user.Burck
Then who is the victim?Fidellia
The server I assume. OK yes Referrer can be faked. This is not a problem for a RESTful webservice, but it might be a problem for stateful interaction, in a game for example, where you want to be sure that the user was on the page they claimed to have been on.Fidellia
A CSRF is when a remote site/attacker tricks a user/browser of a user site into performing an action on the user site. CSRF Tokens protect against that. A remote site/attacker CANNOT trick a user/browser into changing the referrer it sends to the user site. End of argument.Dayflower
B
7

Yes it is. if you take some precautions.

This is a 12 years old question which is first result to appear so i'm going to answer it. in this 12 years things has changed a lot. so while it could have been a poor choice back then, now it's an easy to implement and a reliable solution.

Main source of doubt about using referrer was if there was no referrer header in the request. this can happen in multiple occasions like attacker omitting referrer, requesting from a secure page to an insecure one, Proxies or users omitting it by choice or omitting it by meta tags.

in all cases above you should strictly ignore and fail requests without a valid referrer. it's obvious why you should fail when attacker omits the header and you can simply not omit it in meta tags in your page. if user decides to omit it by choice, well it's their choice and it will break functionality, just the way disabling cookies or javascript would break most websites.

Sending request from a secure page to an insecure one is not a big deal either. because in this 12 years. web has changed a lot and most websites don't need to deal with insecure endpoints at all actually if you do, you wont have that assuring lock logo appearing in the address bar.

Talking about secure endpoints, there is no worry about proxies or ISPs omitting the header either, because whole request including headers is encrypted and interceptors simply cant check headers let alone modify them unless they have access to user's device which overall makes it a very rare case.

But cant referrer be faked ?

Faking a referrer is a both easy and hard thing to do. it's feasibility depends on who you trust in the process. lets consider this awful strategy:

User logs in to website example.com and example.com/login checks if user is a valid user and then redirects user to example.com/sensitive, the example.com/sensitive page then evaluates referrer and if it is from example.com/login, prints sensitive data. this is awful because user can easily fake the referrer on his/her own browser. but whole idea of protection against CSRF attack is not for cases when you don't trust the user. it's for when you don't trust the request to be genuinely sent from the user. which means in order to fake the referrer the attacker needs to somehow modify user's device and honestly if the attacker has that access they wont bother with sending third-party requests after all.

So, nothing to worry about ? Almost.

there are two tricky situations with easy solutions that comes to mind.

A. not checking the referrer properly. what it means ? assuming that your domain is example.com and you are just checking whether example.com exists in referrer string or not. then you can falsely consider example.com.evil.com as a genuine request. the solution is to check for example.com/ in SERVER_NAME which includes your domain no the whole address. (i checked this in my local PHP server and worked fine. you might need to test with your own environment and find another solution if this is not applicable)

B. Taking into account redirects from your own website. if your website has an endpoint to redirect to external resources like this : example.com/redirect?url=extenal.com an attacker can exploit it and make requests like this example.com/redirect?url=example.com/sensitive

to solve this problem it's better not to change state (modifying database records, etc) with GET requests. as precautions you can also check if the request is from your redirect endpoint or not and also not to redirect to your own domain in your redirect endpoint.

Brick answered 30/11, 2021 at 7:6 Comment(1)
Very nice explanation! I just want to point out that vulnerability B. could also be prevented by using CSRF Tokens even during GET requests. But the most important detail is, never use GET methods for state changing requests.Pipistrelle
T
-9

no is not enough, it is very easy for the attacker to do that FOR the client, as you ask, all the attacker has to do is get the user to click in a link created by him, from that point, is game over

The attacker will copy the form used in the original site, and spoof the rest because now the code is on his own site, then submit that to the victim site

As you mention on the question, tokens are the norm when it comes to prevent CSRF

Thermostatics answered 12/9, 2009 at 1:14 Comment(0)
F
-10

Follow the norm: use tokens.

Checking the referrer actually does nothing, because the request is coming from that page anyway! The problem you are trying to prevent is the page being requested without the user doing anything; not the page being hit itself.

Tokens are the way to protect against this. You generate one, store it in the session, and write it to the HTML, then, upon posting, you check the one you receive, and see if it matches the one you expect. If it doesn't, you fail. Either way, you generate a new token afterwards.

It may also be relevant to consider that this will mess people up if the have multiple pages; so you may like to make a different token per page.

Falcongentle answered 12/9, 2009 at 2:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.