views:

136

answers:

5

I have a PHP script that checks the HTTP Referer.

if ($_SERVER['HTTP_REFERER'] == 'http://www.example.com/') {...}

However, this seems inherintly unsafe ... because what happens if the user goes to 'http://example.com/' or 'http://www.ExaMple.com' (both of which don't match the equality test).

Question: what's a better equality test to ensure that the HTTP Referer is coming from 'example.com' ?

+1  A: 

Obligatory response: HTTP_REFERER can be spoofed so there is no way to be 100% sure anyone came from a specific website.

However if you do want to rely on it you can use a regex to look for "example.com" in the HTTP_REFERER. stristr() would also work, and probably would be recommended since it would be faster then a regex. It's also case insensitive so it would match "ExaMple.com" as well as 'example.com".

John Conde
I know, thanks. But that's not the question.
Hank
(It's still a decent first line of defense, but thanks for mentioning it regardless)
Hank
but wouldn't *stristr* also match on "notmyExample.com" which would be undesirable ?
Hank
+1  A: 

Hope you don't check it for anything significant.

you can use parse_url() function to get hostname part and to check if HTTP_REFERER contain actually an url.
you can also just substr www. from hostname.
character case is not important as it's always lowercase

or use a regexp.

Col. Shrapnel
A: 
if (strtolower($_SERVER['HTTP_REFERER']) == 'http://www.example.com/') {...}

How about...

$parts = explode('/',$_SERVER['HTTP_REFERER']);
if (in_array('example.com',$parts) || in_array('www.example.com',$parts)) {...}
Brant
Not sure this will work all the time because that assumes 1) a trailing slash, 2) that "www." is present instead of the user going directly to http://example.com
Hank
URLs should always be canonicalized, i.e. redirect secondary domain to primary one (when multiple domains are used). http://en.wikipedia.org/wiki/Canonicalization
jholster
@Hank - Check my answer again...
Brant
+3  A: 

parse_url() combined with a bit of string juggling should do what you want. Try this:

$url = parse_url($_SERVER['HTTP_REFERER']);
//take the last two 'dot segments' of the host
$hostOnly = implode('.',array_slice(explode('.',$url['host']),-2));
if (strtolower($hostOnly) == 'example.com') {
    //stuff
}

Note that parse_url() can fail on badly formed URLs, so you might want to add some error checking to be safe. HTTP_REFERER could easily be filled with junk.

zombat
A: 

Using a regex, this would become

if(preg_match("%(http://)?(www\.)?example\.com(/)?%i",$_SERVER['HTTP_REFERER'])) { ... }
Arda Xi