3

This is not my main anti-CSRF mechanism; I know that https requests don't have a referer header; I know users or firewalls can remove it or set to an arbitrary fixed value.

I intend this mechanism just as a possible added security layer preventing CSRF in case my main mechanism is bypassed for some reason.

My code will be something like this:

if(isset($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST']))
if(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)!=$_SERVER['HTTP_HOST'])
exit('Anti-CSRF mechanism!');

I think this has no support and usability problems. right?

1

2 Answers 2

7

Although checking the HTTP referer header is a method of mitigating CSRF, this proposed PHP implementation is bypassed by omitting the referer, which can be done using a meta referer policy. If the CSRF exploit originates from an HTTPS site then the referer will be absent, and this absent case is not checked for in the above code. The lack of a referer should be considered an attack. However, a much better anti-csrf method is using a synchronization token.

3
  • How is it trivial to bypass? Yes the referer can be spoofed but not during a CSRF attack. Direct quote from OWASP : Although it is trivial to spoof the referer header on your own browser, it is impossible to do so in a CSRF attack
    – pllee
    Oct 8, 2015 at 18:37
  • @pllee the PHP snip does not call exit() if the http_referer is absent. Although the referer cannot be changed, it is trivial to omit using a meta referer policy.
    – rook
    Oct 9, 2015 at 9:31
  • Thanks for the clarification is there any potential security holes in checking the referer/origin and blocking if it is null ? Assuming the user's browser has no header changing plugins and they are not on an 2007 version of FF which has a referer bug in it.
    – pllee
    Oct 9, 2015 at 14:18
0

There are ways to lose CSRF mitigations using Referer at HTTP. Practical demonstration could be accessed here: http://attacker.kotowicz.net/lose-referer/test.php#

Quoting bypasses from above link:

Bypasses: GET requests

data: with location= - Chrome / Safari
window.open() - MSIE
data: with meta refresh - Firefox / Opera / Chrome / Safari 

POST requests

data: with meta refresh & form submit - Firefox / Chrome / Safari

A better option could be Origin or NoRefferer.

You must log in to answer this question.

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