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?
Among other things, using the referrer won't work for users whose browsers (or corporate proxies) don't send referrers.
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.
Among other things, using the referrer won't work for users whose browsers (or corporate proxies) don't send referrers.
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).
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.
GET
methods for state changing requests. –
Pipistrelle 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
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.
© 2022 - 2024 — McMap. All rights reserved.