PHP Code security problem with header(“Location: …”);

Some people do this in their code to check if the user is logged in:

if(!isset($_SESSION['loggedIn']) || $_SESSION['loggedIn'] == false)
	header(sprintf("Location: http://%s/login.php", $_SERVER['SERVER_NAME']));

//Handle POST input for CMS
	//delete stuff

//display the rest of the page

You get the point.

This is NOT as secure as you might think. You are depending on the user’s browser to redirect to that particular page.

Should the browser be set to ignore that, they can view your page.

I’ve got this concept code:

Then you open a telnet connection to that particular page, for this example it’s index.php on localhost:

  • Open cmd
    • Start > cmd
  • telnet to localhost
    • Type
      telnet localhost 80
  • Set the parameter
    • Press Control + ]
    • Type
      set localecho
    • Hit enter
  • Send the HTTP request
    • Type
      GET / HTTP/1.1
    • Hit enter
    • Type
      Host: localhost
    • Hit enter twice

You’ll see the following result:

HTTP/1.1 302 Redirect
Content-Type: text/html; charset=UTF-8
Server: Microsoft-IIS/7.0
X-Powered-By: PHP/5.2.9-1
Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/
X-Powered-By: ASP.NET
Date: Tue, 14 Apr 2009 20:19:22 GMT
Content-Length: 156

Document Moved

Object Moved

This docume nt may be found hereSecure stuff Connection to host lost.

As you can see the ‘Secure stuff’ sentence is still printed. This is only 1 line, but it is possible that you display a whole page, and this can be exploited by a hacker.

So what can you do?

  • Add a die() after the header
  • Put the rest of the page in the else block
  • Check if user is logged in in each POST which accesses secure stuff.

The last one is a little harder, since you have to do it on every if statement. I’d go with the first, but the second is as good.  If you use the last one: remember that the hacker still can see the whole page, which might give him sensitive information.