I'm attempting to use strpos to see if a HTTP_REFERER contains a certain URL ($referral), but for some reason the following code isn't working. However, if I replace the variable $referral with a string of the same contents, it seems to work. Can anyone tell me why, or what I'm over looking?
//$_SERVER['HTTP_REFERER'] = http://www.example.com/something/somefile.php
$referral = 'http://www.example.com/';
$server = $_SERVER['HTTP_REFERER'];
if(strpos($server,$referral) !== false)
{
echo 'true';
}
else
{
echo 'false';
}
//outputs 'false'
Perhaps $server is not http://www.example.com/something/somefile.php.
When using:
$referral = 'http://www.example.com/';
$server = 'http://www.example.com/something/somefile.php';
if(strpos($server,$referral) !== false)
{
echo 'true';
}
else
{
echo 'false';
}
Output is true
How, and if the $_SERVER['HTTP_REFERER'] is set depends on the user agent. This value needn't be set, and even if it is, it's not reliable. Taken from the PHP documentation:
'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.
That's, I think, what you're overlooking here.
If you are accessing domain without any path eg: http://www.example.com, then your script would return false since there is no backslash at the end. Also you may not be opening the site with www or having and ssl (https)
Could you please post var_dump($server) on the page it doesn't work?
Related
I'm still new to php and still experimenting about. I'm getting an undefined index for the variable :
$httpreferer = $_SERVER['HTTP_REFERER'];
The entire code of the page is:
<?php
ob_start();
session_start();
$current_file = $_SERVER['SCRIPT_NAME'];
$httpreferer = $_SERVER['HTTP_REFERER'];
function loggedin(){
if(isset($_SESSION['user_id'])&&!empty($_SESSION['user_id'])){
return true;
}
else
{
return false;
}
}
?>
Sorry if this is a lame question. I'm still a beginner.
Thanks in advance.
The browsers (clients) are free to send any HTTP headers they like. You cannot trust them!
Check whether the client provided one using isset():
if (isset($_SERVER['HTTP_REFERER'])) {
// do something
}
Bear in mind that this not tell anything about the data itself. It may be anything.
If the visitor doesn't have a referrer (for various reasons he may not, like directly accessing a page - and not clicking a link on another website, or coming from an HTTPS link), then this variable will not be there.
What you can do is this
$httpreferer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
This is a ternary operator.
http://php.net/manual/en/language.operators.comparison.php
I can't seem to work out why the below sends ALL traffic to the page-not-found page, even if referred by Paypal. Any ideas?
$refererUrl = $_SERVER['HTTP_REFERER'];
$Exploded = explode("/",$refererUrl);
$urlToCheck = $Exploded[3];
$findURL = strpos($urlToCheck,'paypal.com');
if($findURL === false){
header('location:/page-not-found');
} else {
/* Do something if page referred to by Paypal */
}
You are checking if 'paypal.com' is present in $Exploded[3]. Why do you expect that part of the referer url to be the hostname? Array indexes start at 0, so counting from left to right would give you the following, indicating that 2 would be the correct index.
$Exploded = explode('http://www.google.com/?q=foobar', '/');
// $Exploded now contains:
0: http:
1:
2: www.google.com
3: ?q=foobar
However, it would be more safe to use some utility that will parse arbitrary URLs and read the hostname from the interpreted url. You could do something like this (untested):
$referer = parse_url($_SERVER['HTTP_REFERER']);
if($referer['host'] != 'paypal.com')
header('location:/page-not-found');
else
/* Do something if page referred to by Paypal */
parse_url doc: http://php.net/manual/en/function.parse-url.php
Are you sure that HTTP_REFERER is set? If you have a look at the documentation it says
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.
Is it correct?
$urlToCheck = $Exploded[3];
If your reffer looks like http://www.example.com/....
the by exploding by "/" you will never got domain in 3rd index. It should be 2.
Try using
$urlToCheck = $Exploded[2];
How do I create a PHP script that will redirect to a custom URL when link added in the URL. For instance, when a user visits this:
http://mydomain.com/link.php?=http://www.google.com
It should redirect them instantly to google.
Ideally, is it possible to ensure that the click itself came locally?
I am aware that this is most likely a very basic PHP code but note that my knowledge of it is very limited which is restricting me from writing it.
You can use the HTTP_REFERER of $_SERVER variable to check whether it is from the local domain.
Reference: http://php.net/manual/en/reserved.variables.server.php
For redirection, try using the below
http://mydomain.com/link.php?r=http://www.google.com
header("Location:".$_GET['r']);
Reference: http://in3.php.net/manual/en/function.header.php
I hope the following works for you, you can hard code the $domain variable as mydomain.com
$url = "http://www.php.net/index.html";
$domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
$refDomain = str_ireplace('www.', '', parse_url($_SERVER["HTTP_REFERER"], PHP_URL_HOST));
if(strcmp($domain, $refDomain) == 0)
{
//your code goes here
header("Location:".$_GET['r']);
}
http://mydomain.com/link.php?url=http://www.google.com
<?php
header("Location: {$_GET['url']}");
?>
This?
Ok, I would like to add a complete answer here.
You could use header to send a redirect header like MrSil said,
header("Location: $url"); // will redirect to $url!
If you want to prevent other people from using your redirect script, you can do something like:
$ref = $_SERVER['HTTP_REFERER'];
$host = parse_url($ref, PHP_URL_HOST);
if($host !== "mydomain.com"){
// out side request
}
But then, HTTP_REFERER can be easily spoofed. So, what would be a better check?
CSRF Protection. It might look like overkill, and it is also not the perfect way to do this stuff, but it helps.
Also, I don't think a perfect solution exists.
Read this for further info about CSRF.
Let say we've the following
Objective : User will post certain exact URL $refere to lock viewing text content and only be allowed for view if the viwer is coming from the same exact URL $refere.
$refere = "http://www.site_site.com"; // User will post it
$r = $_SERVER['HTTP_REFERER']; // To get real referral
and i want to do the following
<?PHP
if(stripos($r, $refere) == false){
echo "Wrong";
} else { ?>
echo "Go";
}
?>
It always gives me $r = $_SERVER['HTTP_REFERER']; blank ! so does it deprecated on any PHP version 4 or 5 whatever !
Also
what is the user posted $refere like https:// or missed www. or only posted site_site.com while the $r = $_SERVER['HTTP_REFERER']; showing www.site_site.com
so can anyone help me to adjust this code to be working fine no matter the user posted the $refere link fully or only site_site.com.
The $_SERVER['REFERER'] variable will only be set when you click a link to your page from another page and if the browser (or an eventual proxy or firewall you're on) isn't removing the referer header.
To your second question: do some string comparisons. The functions strpos() and substr() will be of great help.
So, I need to check the referrer to a page using php, and if it is *.example.com, or *.anothersite.com, execute code, but if not, redirect elsewhere.
How would I go about checking if the HTTP_REFERER is equal to those values, with a wildcard character?
Thanks!
EDIT: The url will contain more than one domain, so the regex needs to match the FIRST occurance found.
Should do it:
$allowed_host = 'example.com';
$host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
if(substr($host, 0 - strlen($allowed_host)) == $allowed_host) {
// some code
} else {
// redirection
}
Other answers' checks' are good but are not strictly bound to your website. So for example referer with value http://attacker.com/www.example.com/ will pass almost all the checks. And it is very easy to make such site and just send a cross-domain request.
There is a reliable and secure method to check if referer is really your domain. Of course referer can be spoofed, but a victim of an attacker site will send correct referer.
The trick is in ^ special character. Here is the magic regex:
^https?://(([a-z0-9-]+)\.)*example\.com/
^ - ensures that we are at the start
https? - protocol - http or https
(([a-z0-9-]+)\.)* - matches subdomains, also of higher levels, if any
example\.com - matches main domain
/ - ensures start of path so domain name cannot continue
$ref = $_SERVER['HTTP_REFERER'];
if (strpos($ref, 'example.com') !== FALSE) {
redirect to wherever example.com people should go
}
if (strpos($ref, 'example.org') !== FALSE) {
redirect to wherever example.org people should go
}
Of course, this only works if the referer is "nice". For instance, coming from google you could possibly have "example.org" in the search term somewhere, in which case strpos would see it, and redirect, even though you came from google.
preg_match('/(.+?)\.example\.(com|org)/',$_SERVER['HTTP_REFERER'])
This will only match an address that has a subdomain, and it also will not continue looking for anything beyond subdomain.example.com or .org. i.e. subdomain.example.com/some-other-stuff. Do you need to also match either of these?
Correction - this will match www.example.com but will not match example.com.
Try this:
if (preg_match('/\.example\.(com|org)/', $_SERVER['HTTP_REFERER']))
{
// execute your code
}
else
{
header("Location: http://example.com/redirectpage.htm");
exit();
}