Determining Referer in PHP
Asked Answered
T

5

106

What is the most reliable and secure way to determine what page either sent, or called (via AJAX), the current page. I don't want to use the $_SERVER['HTTP_REFERER'], because of the (lack of) reliability, and I need the page being called to only come from requests originating on my site.

Edit: I am looking to verify that a script that preforms a series of actions is being called from a page on my website.

Towne answered 3/10, 2008 at 7:17 Comment(4)
Why do you say $_SERVER['HTTP_REFERER'] is not reliable?Hazelwood
The PHP implementation is reliable. The problem is that not ever browser is sending this, and you can even modify it if you like. So it is not reliable that is is correct from the client's side.Piccard
A possible way is to put a unique key (eg. a GUID) in one field of your page, and send it back in the next request.Tremulant
Find out the server's IP address and use $_SERVER[REMOTE_ADDR].Roi
E
95

The REFERER is sent by the client's browser as part of the HTTP protocol, and is therefore unreliable indeed. It might not be there, it might be forged, you just can't trust it if it's for security reasons.

If you want to verify if a request is coming from your site, well you can't, but you can verify the user has been to your site and/or is authenticated. Cookies are sent in AJAX requests so you can rely on that.

Eh answered 3/10, 2008 at 7:33 Comment(4)
If you want to use this method, you should still check the referrer as well to prevent CSRF en.wikipedia.org/wiki/Cross-site_request_forgeryEdlun
Ideally you should use a unique token per session per user (per request if you're paranoid) to prevent CSRF attacks. Checking the referrer is just security by obfuscation and not quite a real solution.Eh
@Eh no, checking the referer is not 'security by obfuscation'. An attacker trying to perform a CSRF attack cannot control the referer sent by the victim's browser, so checking it does protect against CSRF. However, I'll stand by your conclusion that you should use a CSRF token instead, since the referer-checking approach has disadvantages including leaving you vulnerable if you have an open redirect on your site and breaking for user agents that strip the referer.Oldfangled
@MarkAmery it all depends what you are trying to defend against of course, but using client-specific http headers is overall not a very strong security model.Eh
L
23

What I have found best is a CSRF token and save it in the session for links where you need to verify the referrer.

So if you are generating a FB callback then it would look something like this:

$token = uniqid(mt_rand(), TRUE);
$_SESSION['token'] = $token;
$url = "http://example.com/index.php?token={$token}";

Then the index.php will look like this:

if(empty($_GET['token']) || $_GET['token'] !== $_SESSION['token'])
{
    show_404();
} 

//Continue with the rest of code

I do know of secure sites that do the equivalent of this for all their secure pages.

Luminal answered 4/12, 2012 at 13:19 Comment(2)
Here is a link for more on CSRF tokens: en.wikipedia.org/wiki/Cross-site_request_forgeryLuminal
Are you sure that it is $_GET['token'] == $_SESSION['token'] and not $_GET['token'] !== $_SESSION['token']?Lamontlamontagne
D
19

Using $_SERVER['HTTP_REFERER']

The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.

if (!empty($_SERVER['HTTP_REFERER'])) {
    header("Location: " . $_SERVER['HTTP_REFERER']);
} else {
    header("Location: index.php");
}
exit;
Dichasium answered 26/9, 2012 at 20:12 Comment(0)
M
0

There is no reliable way to check this. It's really under client's hand to tell you where it came from. You could imagine to use cookie or sessions informations put only on some pages of your website, but doing so your would break user experience with bookmarks.

Methadone answered 3/10, 2008 at 7:36 Comment(0)
B
0

We have only single option left after reading all the fake referrer problems: i.e. The page we desire to track as referrer should be kept in session, and as ajax called then checking in session if it has referrer page value and doing the action other wise no action.

While on the other hand as he request any different page then make the referrer session value to null.

Remember that session variable is set on desire page request only.

Borstal answered 23/6, 2011 at 6:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.