PHP header(); reliability - php

I need to redirect users if I don't want them to be able to access a certain page. How reliable is header('Location: ../acc/login.php'); for example? Can browsers ignore 302 errors, and is this the right way? Thanks in advance!

It depends a lot what you're trying to do. Technically spoken, header() is somewhat reliable. Only somewhat, because many PHP users have problems with it and to not get it to work.
PHP will prevent it from working if output has been already send to the browser. A drastic example:
<protected page content here>
<?php
header('Location: login-first.php');
exit();
?>
This would not work at all. You would eventually see even an error message with a warning.
Headers - by design - need to be send out before any other content (response body). They can not be send any longer if the response body has already started and PHP can't help you then in that case.
However, if you send headers before the response body, that function will work. Also the risk obviously to mess something up is not that drastic any longer, too:
<?php
header('Location: login-first.php');
exit();
?>
<protected page content here>

You can rely on header(), but make sure you called die(), exit() or return after that. Otherwise, script will continue its execution, which is potential security issue.

The browser can ignore header('Location: '); forwarding.
That is why you should always return after a call to a header() forward so the rest of your code does not execute should the browser not honor the forwarding.
It is the correct way to do things tho.

I would send the header command and then the exit command "exit()" (to stop running the php code on the server) before displaying the rest of the page. This way the user would never be sent the page content even if they ignored the 302 redirection.
And yes the user can ignore the 302 redirection:
http://www.webmasterworld.com/html/3604591.htm

header is 100% reliable.
However header('Location: ../acc/login.php') will be evaluated in the browser to a real location on your website, and ../acc/login.php wil not form a url that is valid!

Related

PHP header location not working with clean urls

<?php
$result = mysqli_query($link, $query);
$url=$_SERVER['REQUEST_URI'];
if (!$result) {
$url.="/signup";
header("Location:".$url);
} else {
$url.="/home";
header("Location:".$url);
}
?>
Hello friends I am in a bit problem I am doing a project and using clean urls my htaccess is good everything is going good but after a signup form submission when I want to change header location
php gives an error can't change header location
kindly help
I would post a comment but I dont have enought rep.
Anyway, probably you are seeing error about headers already sent. It is common problem and it have nothing to do with clean urls. what you can do?
1. Make sure you are not outputting anything before header() call
Problem is based on fact how web server and HTTP works. When you are outputting server will send headers and content as soon as it is ready. And you may be outputting even whitespaces, so double check this first.
2. Turn on output buffering
If for any reason you need to output something before headers manipulation, you can turn on output buffering. This way server first "buffers" your data and then sents everything out. Hovewer you are paying in load time for this. Use only rarely, when it is really needed!
You can use a ob_start()for this
If that is your PHP script, I can see whitespaces before <?php tag.
<?php
^^^^--- WHITESPACES
These whitespaces will be written to output buffer even before PHP interpreter kicks in, and when you call header() it will give an error. This is because no output should be sent to client before calling header().

Header redirect being VERY funky.. What's going on?

This is really weird.. I have the following redirect in a file:
header('Location: http://google.com');
It doesn't work. The page loads and the user is not redirected. However, if I add a die() statement below that line, like this:
header('Location: http://google.com');
die('what the heck is going on here?');
Then the redirect magically starts working!
I'm at a total loss as to why this is happening, and I have no idea how to debug it.
Can anyone give me any advice on this?
You are supposed to exit after sending a location header. Sending any header does not affect the flow of the script so any code after it still executes. If anything causes a different response status code to be set the redirect will not happen at all.
A Location header by itself does nothing - only together with the proper 30x response code it will cause a redirect. PHP sets this response code manually when sending a Location header but your code might modify it.
Probably your script isn't ending after the header call.. Make sure you end the script.

more than one header in chrome not working - php

Im using PHP to track the clicks of all mailto links by rewriting the mailto: to my script and then setting the header of the referring page.
Initially I just had:
header("location: mailto:email#address.com");
...but this has an undesirable effect in IE8: it opens 2 email windows. So, in my attempt to resolve that issue I am now using:
header("Status: 200");
header("location: http://mypage.com");
header("Refresh: 0; url=mailto:email#address.com");
This works fine in IE but not chrome. I threw the "status" in there hoping to solve the mystery.
Other than detecting the browser and issuing different commands, what else could one do?
A location header should be accompanied by a 30X status code (like 302), not 200.
Check this out > http://php.net/manual/en/function.header.php
Especially those two parts:
The second special case is the
"Location:" header. Not only does it
send this header back to the browser,
but it also returns a REDIRECT (302)
status code to the browser unless the
201 or a 3xx status code has already
been set.
<?php
header("Location: http://www.example.com/"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
?>
You send 200 and 302 at same time, and also you didn't follow the exit; rule.
You can play with my suggestions (especially the exit; part).
!!! Note !!! There was a bug in the past that makes the Chrome not to work if header("Status: 200"); wasn't set first, but not sure if it's fixed yet.
it would probably be better to use some AJAX to handle your problem here, and if your going to use AJAX use JQuery its just easier
firstly though mailto is not a preferred method on the web any more its too clunky and relies upon the default email client of the user being set up which in most cases you cannot rely upon.
So to address that have a link that is styled to look like your button.
once you have this use JQuery to send an ajax request to a PHP script that performs the counting and then if you wish upon receipt handle the success with a redirect (I only include that because I am unsure what your redirect achieves).
Its clean quick and the user will not notice a difference apart from your site will probably experience a speed increase :) hope this helps
Header location redirects the browser, so the other headers are ignored. You should send this header always as the last one. Also it's not good idea to execute any PHP code after you send the redirect.
You probably want to do this:
On first page:
header("Status: 200");
header("location: http://mypage.com");
exit();
On the http://mypage.com:
header("Refresh: 0; url=mailto:email#address.com");
The weird thing about chrome: it accepts the following header refresh.
<meta http-equiv="refresh" content="4; url=page.php" />
<button value="go further">
I place a button below this refresh for the browsers who does not support any type of header refresh.

Are commands executed after the "header()" function in PHP?

For example, here:
<?php
session_start();
if (!isset($_SESSION['is_logged_in'])) {
header("Location: login.php");
die();
}
?>
<Some HTML content>
Is die() really necessary here ?
Is die() really necessary here ?
It is: Otherwise, the client will still get the HTML code in the response body. The header asks the client to terminate and go to the new page, but it can't force it.
The client can always continue listening to the response, and receive everything output afterwards, which is a fatal security hole e.g. when protecting sensitive data in a login area.
Yes, die() is necessary. A call to header("Location: some-location.php") sends the specified header (a 302 redirect in this case) to the browser; but it DOES NOT terminate the script. It becomes more important if the lines after the redirect statement contains PHP code which may execute unintentionally. So if want to send the redirect header and abort any further processing you must call die, exit, return or any other similar construct.
Note that it is possible to perform further processing after sending the redirect header.
Yes. Simply generating a header, even the Location header, does not terminate the current script. The HTML output will be visible in e.g. a packet sniffer.
I found that: http://www.figured-it-out.com/figured-out.php?sid=181
So according to this it seems that some browsers just stop receiving the html content and redirect directly to the new page where other browsers like IE still wait untill the loading of the page is ready.

Should I use "return;" after a header()?

Quick question, I noticed that on some of my header directors I was getting some lag while the header processed. Is using return standard after using headers? Also if you use a header on pages you don't want directly accessed, such as processing pages will return; stop that processing even if the page is not directly accessed? IF return is a good idea would it be better to use exit()?
header("Location: ......"); exit; is a fairly common pattern.
You do not need to supply return; after calling header but I know some people use the convention of supply exit; after header call to ensure the code below will not execute during a redirect.
Keep in mind you can use header() for other things besides Location: redirects:
header("Content-type: image/jpeg"); // for example
The reason you would exit after a header redirect is, any content output after a header() redirect, will (most likely) not be seen by the browser.
More importantly you wouldn't want any code to be executed after a header() redirect, so calling exit() after a redirect is good practice.
When you send the header, it is but a mere advisory to the client(the browser) that you think they should request another url instead. However, nothing can stop them from not following your recommendation. They can continue reading more data from the current url, if your server keeps feeding it to them. This is why you generally see php code that calls exit() after sending a redirect header, because if you stop outputting more data, there is nothing for them to read.
Aside from keeping them from reading unintended data, there's other reasons:
Maybe it's just plain senseless for the rest of the script to continue executing, wasting resources.
Maybe runtime errors would occur if the script were to continue(ex, there were missing variables, or a db connection failed).
Maybe logic errors would occur if the script were to continue(ex, user input validation/authentication failed).
It's up to the client to determine what to do after an header("Location: ...").
Any code after header() will be executed regardless. Putting an exit(); just after the header is a safeguard and is required for securing your site.
If you have some candy after header("Location: ..."), the only thing the browser have to do is to ignore the request. Then it'll be clear as day. With exit(); you're stopping execution of the page and hopefully there are no other attack vectors to your app!

Categories