$_SERVER['HTTP_REFERER'] is always empty - PHP - php

<?php
$camefrom =$_SERVER['HTTP_REFERER'];
if ((substr($camefrom,0,26) == "http://www.fromperson.com")
header( 'Location: http://toperson.com' ) ;
?>
I need to redirect to www.to.com if the request was made from www.from.com. This code resides in www.thridperson.com/index.php
$camefrom is always empty.
I have read that $_SERVER['HTTP_REFERER'] is not reliable. Is there any other way to perform this redirection?
Note: I have lost the access to old domain i.e fromperson.com. So, I cannot change this redirection logic it has to be done this way and it has to done only in thirdperson.com/index/php

$_SERVER['HTTP_REFERER'] is indeed unreliable. A client (browser) is not required to include it in the request. If you need a bullet-proof solution that will always work you will have to moddiffy your application on `fromperson.com' to include some GET parameter when linking to your web page, and then you can check if that GET parameter exists and then do the redirect.

No way to do according to my requirement

Related

Redirections in PHP

If I want to redirect a user in PHP, all I've ever known to do was use the header('Location:' http://www.example.com) but I've been reading that this isn't the best way to redirect a user from page to page internally. What are some other options you can redirect a user?
Example: at the bottom it says:
Something Important to Remember
...I don’t recommend, for example, using header() to bounce your users around to different pages; there are better methods that reduce the number of page loads and give the user a more fluid experience...
http://tinsology.net/2009/06/creating-a-secure-login-system-the-right-way/
The snippet you provided is referring to issues where page1.php might execute some code followed by header('Lodation: http://www.example.com/page2.php'); and where page2.php then executes some code followed by header('Location: http://www.example.com/page3.php'); etc. This is very bad for user experience, and not very good for managing code either.
In cases where you genuinely need to redirect a user (301 redirect is probably the most common), using header is perfectly acceptable.
It isn't bad. However you could add 301 response code to make it more better, it is also better for Google to determine he should not visit that "old" site anymore.
<?php
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.new-url.com" );
?>
This is the accepted method for PHP-based redirection. If you can accomplish the redirect prior to PHP script execution, then you should - through .htaccess or server-level aliasing.
Check out the manual on header: http://php.net/manual/en/function.header.php
It's always sensible to avoid using header() internally because sometimes headers are already called. JavaScript redirects are absolutely fine and are used systematically in a lot of web applications. Browsers and search engines don't discriminate against or dislike JavaScript redirects. A simple example:
<?php echo '<script type="text/javascript">window.location.href="index.php"</script>'; ?>
Or using a variable:
<?php echo '<script type="text/javascript">window.location.href="' . $page . '"</script>'; ?>
Just use
header("Location: http://www.example.com");

How to end a PHP session on page close

I have several pages inside an AJAX directory. I don't want these pages accessible directly so you cannot just type in the URL of the page within the AJAX directory and access it. I "solved" this by using a PHP session on the page that calls it as follows:
Main page:
<?php
session_start();
$_SESSION['download']='ok';
?>
and on the ajax page I have this:
<?php
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;}
?>
The only problem is that if a user goes through the correct process once, the cookie is stored and they can now access the page directly. How do I kill the session once they leave the parent page?
thx
why use session ?
if i understood what you want:
<?php /// Is ajax request var ?
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=="xmlhttprequest") {
// do your ajax code
} else {
// redirect user to index.php since we do not allow direct script access, unless its ajax called
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit();
}
} ?>
A really simple solution is to open up each of the files you want to protect from direct URL entry & add the following to the top:
<?php if (isset($_GET['ajax']) != true) die();?>
Now get rid of your redirect script since it's useless now. You don't need to use sessions for this. Every time you request a page, use it's direct URL, just add ?ajax=1 to the end of it.
By adding the ?ajax=1, PHP will set a key of 'ajax' to the $_GET global variable with the value of 1. If ?ajax=1 is omitted from the URL then PHP will not set a key of 'ajax' in $_GET and thus when you check if it's set with isset() it will return false, thus the script will die and not output anything. Essentially the page will only output data if ?ajax=1 is at the end of the URL.
Someone could still "spoof" the URL and add '?ajax=1' themselves, but that is not the default behavior for people or web browsers. If you absolutely need to prevent this then it will be much more complicated, e.g. using templates outside of a publicly available folder. Most other "simple" solutions will have the same "spoofing" potential.
There's really no way to accomplish this with a 100% certainty - the problem is, both AJAX and regular web browser calls to your web site are using the same underlying protocol: HTTP. If the integrity and security of your site depends on keeping HTTP clients from requesting a specific URL then your design is wrong.
so how do you prevent people from directly accessing files inside certain directories while still letting the site use them??
Create a controller file. Send all AJAX requests to this controller.
ajax-control.php
<?php
$is_ajax = true;
include "ajaxincludes/test.php";
// ... use the ajax classes/functions ...
ajaxincludes/test.php
<?php
if (!isset($is_ajax) || !$is_ajax)) {
exit("Hey you're not AJAX!");
}
// ... continue with internal ajax logic ...
If clients try to access the file directly at http://mysite/ajaxincludes/test.php they'll get the error message. Accessing http://mysite/ajax-control.php will include the desired file.
I don't think there is a surefire way to do what you are asking, since HTTP request headers can be faked. However, you can use $_SERVER['HTTP_REFERER'] to see if the request appears to be coming from another page on your site.
If the rest of the security on your site is good, the failure of this method would not grant the user access to anything they were not already able to access.
I've never tried this but maybe you could do something with jQuery's .unload() and then call a PHP page to unset() the session.
Why not (on Ajax page):
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;
}
// do whatever you want with "access granted" user
// remove the download flag for this session
unset($_SESSION["download"]);

Sending a request to another site that has a callback that targets my original page

In my test.php file, I sent a request to a Flickr app I have using
header("Location: " . $request);
where $request is the URL that I am trying to reach on Flickr.
For my Flickr app, I have to set a callback URL. When Flickr is done with processing my request, it will call the callback URL.
I would like the callback URL to be my original page, test.php. When I try this, I get stuck in an infinite loop, because test.php is re-sending the request back to Flickr, and Flickr calls my test.php again (repeat ad infinitum until the browser quits).
Is there a way to put some kind of conditional in test.php to check if the request came from Flickr, or at least some way to let the script know that the request has been sent, so don't send it again.
I've already tried it where I changed the callback URL to another page of mine, and that works fine. I'm just seeing if I could re-use the same page.
Its ugly.
The two posted solutions won't work because:
The referer isnt changed on redirect (well it is cleared if its a http meta redirect, but not if its a header redirect. but it doesnt become something else so easy).
Putting exiting after a sent header is generally a good idea if there is something else normaly executed afterwards, but its not related to the problem.
Simply put, if it should be the SAME page, you need to to store in a file or database or something the redirect counts per ip adress/user and break or something but NONE of this is really reliable. You can make it more secure by having a secured token that cannot be reverse engeneered etc but all this doesn't make sense. You could also use cookies. Which is just as unreliable as well.
Regarding your problem, flickr does NOT redirect back to the samep age.
Regarding to their specifications they append ?frob=[frob].
http://www.flickr.com/services/api/auth.spec.html
Check for that:
<?php
if(!isset($_GET["frob"])) {
header("Location: " . $request);
exit();
}
?>
try checking the referer with the $_server['HTTP_REFERER']
[Edited]
I just wanted to say that, you should try adding if condition
// just and example, use some regular expression to check the refere
if($_SERVER['HTTP_REFERER'] != http://flicker.com){
header("Location: " . $request);
}else{
// another code
}
Thanks
As an alternative to checking for the (non-)existence of $_GET["frob"], couldn't you set the callback url in Flickr to be www.mysite.com/test.php?from_flickr=1 and then do
if (!$_GET['from_flickr']) {
header('Location: '.$request);
exit;
}

PHP Redirect after execution of code

I have a php page that takes in a bunch of url parameters and sends out an email. I am trying to have this page call another web page using the same url parameters, after the mail is sent. If I do the following, will my email be sent reliably? Is a redirect what I really want to do?
Update: Thanks for the tips. As you can see by my use of the +, I don't know any php. After reading all the answers so far I have come up with this:
Random code to send email...
file_get_contents('http://www.othersite.com/' . $_SERVER["REQUEST_URI"]. "?". $_SERVER["QUERY_STRING"]);
I believe this should initiate a GET on the other site with all the current parameters, which is exactly what I want. This way I don't have to deal with redirects. Any problems to this solution?
Update 2: Since my url was https, file_get_contents caused me some problems. There are ways to get around this but I just used header for a redirect and all worked well. Thanks everyone!
The question raised in the other answers whether your basic approach is really what you want is valid - check that first. Anyway, if it really is what you want to do (Is your target URL really identical to the one you're on?) you can indeed use
header('Location: http://www.othersite.com/' . $_SERVER["REQUEST_URI"]);
Just note the use of . to concatenate the string instead of +, you can't do that in PHP.
To do it really properly, you could use http_build_url to build a full valid URL from the current GET array. Code from the manual, modified a bit:
<?php
echo http_build_url("http://user#www.example.com/pub/index.php",
$_GET,
HTTP_URL_STRIP_AUTH | HTTP_URL_JOIN_PATH | HTTP_URL_JOIN_QUERY
);
?>
The header location call will be only called after the mail code so it won't affect your email.
Don't forget to call exit() after your header location call.
Also the string concat operator is not + it's . (dot).
if its the same application, why dont you call the same functions ?
if you want you could do file_get_contents .. instead of a redirect for the same effect.
If you just want to hit that page why not use file_get_contents
$data = file_get_contents('http://www.othersite.com/' . $_SERVER["REQUEST_URI"]);
echo $data;
The benefit with this is you don't have to physically go to the other site if you don't want to, equally if you control the script on the other site you could return a true or false in the HTML which could be checked upon return.
For full compliance (sometimes Chrome will not work with just a Location: header)
header( "HTTP/1.0 302 Found" );
header( "Status: 302" ); # this is for chrome compliance
header( "Location: http://www.othersite.com/' . $_SERVER["REQUEST_URI"] );
Another option is to echo the HTML tag:
<meta http-equiv="Refresh" content="1;url=http://www.othersite.com/<?php echo $_SERVER['REQUEST_URI']; ?>">
This allows you to set a delay time for redirecting (usually 1s), which is good in some situations so that the user doesn't become confused by a flash of content. You can put a 'Stand by while we redirect you' message or similar.

php/html - http_referer

I am creating a website and on one particular page, am wanting to send the user back to the previous page. I am fairly new to PHP/HTML and have been using some existing code for ideas and help.
The existing code uses the following method:
if (! empty($HTTP_REFERER))
{
header("Location: $HTTP_REFERER");
} else
{
header("Location: $CFG->wwwroot");
}
However, when I use this code the HTTP_referer is always treated as empty and the user redirected to the root page. Any obvious flaws in this code?
Don't rely on the HTTP Referrer being a valid or even non-empty field. People can choose to not have this set leaving any checks for that variable going to the empty side of the IF-ELSE clause.
You can guard against this by sending along a parameter in either the URL or POST parameters that would hold a value that you can use to redirect the user back to.
You need to use:
$_SERVER['HTTP_REFERER']
isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
If you wanted to send the person back to the previous page and have it work regardless of the referrer being set correctly, you can append a GET parameter to the URL (or POST).. you will need to encode the URL.. Something like
http://www.domain.com.au/script.php?return=http%3a%2f%2fwww.domain.com.au%2fthis-is-where-i-was%2f
You can use PHP's urlencode() function.
Also note that the referer header might be empty or missing anyway, so you shouldn't rely on it at all..
You should use
$_SERVER['HTTP_REFERER']
However look at the register_globals configuration in php.ini, it should be turned off due to security reasons. You can read more on PHP Manual site.

Categories