views:

65

answers:

2

Hey guys,

I have a question about sessions. How do you make a secure login session/cookie. I was looking at this example where they add this array to the session:

$data = array{

    username = $_POST['username'];
    is_logged = true;

}

I was wondering if this is enough? Is it not possible to change the username in the cookie to anything or anyone? What would be a good way to go about this?

Or is this completely safe and am I missing something?

Also, what do you guys think about storing sessions in the DB? I know tha CI has a built in function to do this. Does this cause any problems performance-wise, or is it worth enabeling?

A: 

Yes, that is a really insecure method, and should not be used anywhere if you want to prevent session hijacking.

A more robust method would be generating a unique session ID (eg. a hash) for the user when she logins, and associating the session with this ID server-side. Then send ONLY this session ID in the cookie back to the client. When the client sends a request with the cookie, you grab the session ID and recover the username and any other information associated with it for your request processing.

The client has access to the session ID in the cookie, but that value is meaningless to him since he cannot deduce any information from it, and sending random session IDs has a very little chance of success.

axel_c
Do you mean I should for example apply the md5 function on a userID when I send it to the cookie, or should I use some sort of key when generating the hash so I can recover the userID? Thank you!
Sled
You should generate something non-predictable, otherwise a malicious user could keep generating values with different user IDs and hashing them. You could generate a string of the form [userID][some random data] and then hash that. The random data could be generated using PHP's uniqid() function. That way you'd be pretty safe.
axel_c
+2  A: 

I believe you are misunderstanding how a PHP session is supposed to work. You can safely store the username, login status and other stuff into the $_SESSION array, as this is stored serverside. The only thing sent to the browser is a single cookie (named PHPSESSID unless you changed this in php.ini) containihg the session ID - which is a unique random number.

Once your visitor has an active session every time he requests a page which has session_start() at the top, session_start() will look at the request for a cookie named PHPSESSID, read the serverside session file (if the session exists and is valid) and restore the filed $_SESSION array. This array never needs to leave the server.

The session cookie is set without an expiration date (unless you mess with the session.cookie_lifetime option in php.ini), so the browser deletes it at shutdown. The session file on the server has an expiration time itself, managed by session.gc_maxlifetime (in seconds).

Path to safer sessions:

  • make sure only cookies are used to pass the session id to the browser setting session.use_cookies=1, session.use_only_cookies = 1, session.use_trans_id = 0 (I'll spare you the details of the alternate syntax)
  • prevent session hijacking (i.e. somebody else faking an existing session) storing into $_SESSION something that identifies the browser - a common pattern is to store the md5() of the browser's User-Agent header, the Accept header, the remote IP address or a combination of those; check if it matches at every new request with an existing session id
  • if you're on a shared server you should indeed keep your session files separate from those of your server neighbours: set session.save_path to a folder only you and PHP have access to.

Finally, you should create a script to log users out of the session (and encourage them to use it instead of simply navigating away). This is a sample script:

<?php
  session_start();
  $params = session_get_cookie_params();
  setcookie(session_name(), '', 1, $params['path'], $params['domain'], $params['secure'], isset($params['httponly']));
  session_regenerate_id(true);
  session_destroy();
  session_write_close();
  header('Location: your_login_page.php');
  exit;
djn
Thanks, you're right I was confusing sessions with cookies! Very clear explanation!
Sled