Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Securely creating and destroying login sessions in PHP

This is my code to control authentication on a website. I'm not sure if my logic is correct. If the username and password are correct the following happen:

if(session_start())
{
        session_regenerate_id(true);//without this the session ID will always be the same
        $_SESSION['loggedInUser'] = $uName;
        echo 'You are now logged in';
}
else echo 'Right password/username but session failed to start';

Subsequent pages check to see if the user is logged in by

session_start();
if(isset($_SESSION['loggedInUser'])
{
 //rest of page
}
else echo 'you must log in';

When logging out I have

session_start();//if I don't have this the next line produces an error
session_unset();//destroys session variables
session_destroy();//ends session

I red not to call session_start() on logout but if I don't have it there I get the message Trying to destroy uninitialized session. How can I fix this?

Is it recommend or not to create a finger print based on the IP address and user agent? I red it's bad because multiple computers can share the same IP address if they are in, for example a computer lab, and all the traffic goes through a proxy and the same computer could change it's IP address if it's dynamic. On the other hand, how often does this happen? It may be worth the few blocked valid uses to prevent all session hijacking.

Even if you could recommend reputable articles I should read to learn about this topic that would be great, thanks.

5/6 answers have votes less than 0 :( Could down voters comment so I know what to look out for?

like image 812
Celeritas Avatar asked Mar 19 '13 20:03

Celeritas


People also ask

How PHP session is created and destroyed?

A PHP session can be destroyed by session_destroy() function. This function does not need any argument and a single call can destroy all the session variables. If you want to destroy a single session variable then you can use unset() function to unset a session variable.

What is PHP session_start () and session_destroy () function?

session_destroy() function: It destroys the whole session rather destroying the variables. When session_start() is called, PHP sets the session cookie in browser. We need to delete the cookies also to completely destroy the session. Example: This example is used to destroying the session.

Is PHP $_ session secure?

“Is a PHP session secure? PHP sessions are only as secure as your application makes them. PHP sessions will allow the client a pseudorandom string (“session ID”) for them to distinguish themselves with, but on the off chance that the string is intercepted by an attacker, the aggressor can imagine to be that client.


2 Answers

To securely destroy a session I would use the following code:

session_start();
// Unset all session values
$_SESSION = array();
// get session parameters 
$params = session_get_cookie_params();
// Delete the actual cookie.
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
// Destroy session
session_destroy();

In order to destroy a session you need to start it first, as you have found out it doesn't work if you don't include session_start();

The session_regenerate_id(); Function generates a new session id for the user. If used with true (session_regenerate_id(true);) then the old session id is deleted from the server when it generates a new one. The reason behind generating a new session id on every page is that it makes session hijacking much harder (Nearly Impossible?) to perform because of the users constantly changing session id.

(View PHP.net manual on session_regenerate_id();)

When authenticating a user you should always check something like the IP address or Browser, these are constant things sent in the request to the server that do not change in the life time of your session, and if they do then you know something dodgy it happening. I always create two session variable one that stores the user ID so I can query a database for data, and another that stores the users password, IP address and Browser String all in one hash (sha512).

$user_id = $_SESSION['user_id'];
$login_string = $_SESSION['login_string'];

// Query Database and get hashed password

$login_check = hash('sha512', $password.$ip_address.$user_browser);

if($login_check == $login_string) {
     // Logged In!!!!
     return true;
} else {
     // Not logged in
     return false;
}

The password is secure even though it is being stored in the session. This is because the password is hashed (Twice in this case) and because the session data is not stored on the users computer (Like cookies), it is stored in a session file.

I wrote an article on wikihow.com about secure login and authentication, is can be found here.

like image 31
Dave_Peachy Avatar answered Oct 11 '22 18:10

Dave_Peachy


First of all you should read the Mozilla WebAppSec Security Coding Guideline - Session Management and OWASP A3-Broken Authentication and Session Management. You can configure PHP's session handler to meet these requirements.

The first flaw you should prevent is A9-Insufficient Transport Layer Protection. In short you do not want someone to hijack a session using a tool like Firesheep. This attack can be prevented by forcing the browser to only send the session id over https:

session.cookie_secure=1

You can prevent an attacker from obtaining the session id using XSS by setting the httponly flag:

session.cookie_httponly=1

You always want to use a cookie to store your session id. If the session id can be passed using a GET or POST variable then an attacker could use Session Fixation attack to hijack a session. Another way of thinking about this attack is that you don't want an attacker to create a session for another user:

session.use_cookies=1
session.use_only_cookies=1

Next you want to make sure you have atleast 128 bits of entropy from a CSPRNG. Under *nix systems you can use /dev/urandom:

session.entropy_file="/dev/urandom"
session.entropy_length=16

The session handler isn't everything. You still need to worry about Cross-Site Request Forgery attacks (aka CSRF or "Session Riding"), and Cross-Site Scripting (XSS). XSS can be used to defeat CSRF protection (even with http_only cookies!). Clickjacking can also be used by an attacker to perform unauthorized actions.

After you set these configuration options, just call session_start(). As for destroying the session call session_destroy() when the user logs out, its that simple!

like image 71
rook Avatar answered Oct 11 '22 18:10

rook



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!