views:

184

answers:

8

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?

+2  A: 

Make sure all your gets are idempotent

Idempotent means that doing same request many times has the same effect as doing it once.

Paul Whelan
+7  A: 

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

Alekc
+4  A: 

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('<a href="' . $url . '">Redirecting you to: ' . $url . '</a>');
}

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&amp;userid=MyUserId" />).

Bart S.
It is also easy to create POST either.
Deniss Kozlovs
It is easy to create a POST request. Users are however less likely to make an 'accidental' POST request.
Jacco
chose this one cause the explanation is a bit better. thanks!
contagious
+1  A: 

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.-

soulmerge
A: 

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();

Ólafur Waage
+2  A: 

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.)

David Zaslavsky
+1  A: 
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 <a href=\"somehereharmless.php\">click here</a>");
}
DaNieL
+1  A: 

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.

SchizoDuckie