Redirect after logging out - php

I'm writing a code to redirect to home-page after logging out. I used to use
header("Location: index.php");
but I found in some tutorial that I can use
echo "<script>location.href = 'index.php'</script>";
Now I want to know the difference between both scripts and which is better?

The first one uses PHP, and the second uses Javascript (you'd need to make sure it was echo'ed inside <script></script> tags).
The Javascript solution requires Javascript to be enables and makes the browser do a little more work than the PHP header method. I think the PHP method, header("Location: index.php"); is safer. You would just need to make sure to use die(); after the header command or else risk loading the rest of the page before the redirect can be processed.
Another consideration is that the pure php solution won't work if you've already echo'ed anything (including whitespace). So in some situations, echo "<script>location.href = 'index.php'</script>"; could be a better choice.

Like Stevish mentioned, the second one is Javascript and could be deactivated by the user, if he deactivates Javascript. With PHP the Server will do the redirect.

Related

Check if cookies are enabled without redirect

I need on each page check if cookies are enabled.And use this code.
<?php
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
if(!isset($_COOKIE['COOK_CHK'])){
echo"Cookies are disabled!";
exit;
}
session_start();
?>
However on the first check it gives me false until i don't refresh the page.I include this code in each page so can not redirect every time i load the page as it reduces performance.However i want to use it even if javascript is disabled.Any suggestions?
Can you use javascript? If so, all it takes is a check at the navigator.cookieEnabled variable.
It works in most modern browsers. You can read more about it here: http://www.w3schools.com/jsref/prop_nav_cookieenabled.asp
It's not possible because Cookies are in the browser, and PHP send them when the page has render, so will be available just in the second page.
A possible way to fix this is using javascript.
If you really should do it in PHP, for some crazy reason, send all your request to a main controller and save the state using other method, for example, write a var into a file, then redirect and in the next redirections you'll know if the cookies are enabled without needed any other redirection. Example:
$file = 'cookie_fake_'.$userIP;
if( !isset($_COOKIE['COOK_CHK']) && !file_exists($file) ){
file_put_contents($file, 'dummy');
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
header('Location:/');
exit;
}
if(!isset($_COOKIE['COOK_CHK'])){
setcookie('COOK_CHK',uniqid(),time()+60*60*24);
echo"Cookies are disabled!";
exit;
}
Then you should write something to clean old files every hour or so, of course you can use a cache layer or a database or anything like that instead of writing a file.
Edit: The previous code will be really f** up if the user enables cookies and refresh the page, now I've fixed so it works at the second time it refresh. Not perfect but... You really should do this using javascript.
Cheers.

PHP header(); reliability

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!

How can I send a user to another url without a header redirect?

I'm learning PHP and been looking for this for a while. What I want to achieve is something like so:
if (true/false) {
go to this url;
}
Every time I search terms like php redirects or php links etc., 99% of the time I get something "headers". I read that header redirects can achieve this but no code can go before it, that it must be first on the page else it wont work.
If that's so, then how can I achieve this?
i read that header redirects can achieve this but no code can go before it. that it must be first on the page else it wont work.
That's wrong. There must be no output before this. Thus you have to ensure, that you don't echo, print, ?>something<?php (or whatever) anything before.
if (true) {
header('Location: ' . $url, false, 302);
exit; // Ensures, that there is no code _after_ the redirect executed
}
You can ready everything about it in the official manual. Especially:
Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include(), or require(), functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file.
echo '<script type="text/javascript"> document.location = "http://yoururl.com";</script>'
and this will be executed when this part of script is executed.
You can use this if you need some output before the redirect:
header("refresh: $time_in_seconds; url=$your_url);
You still must call this before output is actually sent however. Send the header, then send your output - the page will "redirect" in the time specified.
Disclaimer: I must admit, I'm not sure what the implications of this are and can't find docs on it, so I can't necessarily recommend it - but I can validate that it works.

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!

securing a webpage without headers

I just read this article on tdwtf.com. Generally, it describes an archiving bot destroying things because it ignores headers. I then realized that I don't know how to do security in a page WITHOUT headers. Therefore my question is:
What security measures can i take besides using headers?
I develop mostly in php, so I'm familiar with header("Location: ") function. But what else is out there?
Ideally I'm looking to replace the logic of
if (!$something_important) header("Location: somehereharmless.php");
with something else (more) secure?
This one works pretty well
if (!$something_important) {
header("Location: somehereharmless.php");
exit();
}
Even if it's bot, so it doesn't respect Location, you will call an exit so the execution flow is halted anyway, so no harm
header: location is fine, as long as you include an exit at the end.
You might also want to include a link or something.
I usually use something like this:
<?php
function redirect($url)
{
header('Location: ' . $url);
exit('Redirecting you to: ' . $url . '');
}
redirect('somepage.php');
?>
This way people can't bypass the redirect, and know that they should be redirected.
[Edit]
Also, always use POST when deleting stuff. It is very easy to create a fake GET (for example <img src="http://www.example.org/action.php?do=SetAsAdmin&userid=MyUserId" />).
Make sure all your gets are idempotent
Idempotent means that doing same request many times has the same effect as doing it once.
I'd say that if you have a PHP script that performs some action which only, say, logged-in users should be able to perform, you must put the check for being logged in right there in the very same script, so you can look at it at a glance and see that the code is secured. My rule is that there are only two valid patterns for protecting secured code:
if (user_is_authorized()) {
// restricted code here
}
or Alekc's
if (!user_is_authorized()) {
// send headers or whatever if you want
exit();
}
// restricted code here
To be perfectly honest, I was rather shocked... or at least disappointed... when I read that article - I can't understand how someone came to the conclusion that a website could be secured with HTTP headers. A header is nothing more than some text that your server sends out. It's an instruction that may be followed or ignored by the client at will (at least, you have to think about it that way for security purposes). As far as I'm concerned, outgoing (response) HTTP headers are pretty much useless for security. (This is not counting things like HTTP authentication, where you send a header and get one back in response... but in that case it's the contents of that reply header that you base your security on, not the header you sent out.)
The reason for the incident reported in the link you provided was the missing exit; statement after the header();. The bot can't do any harm if the script stops.-
if (!$something_important) {
header("Location: somehereharmless.php");
//close all your db connections and other stuff you need to end..parhaps calling a function?
die("If the redirect doesnt start in 3 seconds, please click here");
}
Your solution is
<?php
die($errormessage);
Die will just halt your script, not go through start, don't collect any data that you shouldn't.
Addition to Alekc's answer. If you have many header("Location:") statements and the person qualifies for them all. The last one will fire.
if($foo && $bar)
{
header("Location: somehereharmless.php");
}
if($foo && $baz)
{
header("Location: someotherplace.php");
}
So if that user has all 3 variables set, he will get redirected to someotherplace.php. Unless you have an exit(); or a die(); after the header();

Categories