Note that there are some explanatory texts on larger screens.

plurals
  1. POSecure cookies in PHP sessions
    text
    copied!<p>I have developed a PHP session class and tested it using a few examples (see source code below). It appears to be okay. Now I would like to make this session somehow "secure". I found some sample code which is meant to encrypt a cookie (in Courioso's book Expert PHP and MySQL). Here is this code snippet.</p> <p>Code for encrypted cookie</p> <pre><code>$cookieData = serialize($user); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); srand(); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $encryptedData = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $secret, $cookieData, MCRYPT_MODE_CBC, $iv); setcookie('user', base64_encode).':'.$iv); </code></pre> <p>and a similar code for decrypting the cookie</p> <p>My first question is: can I trust this code. I.e. is it really secure? (I tried some other code samples of that book and found them rather buggy).</p> <p>I do not fully understand how the code for encrypting a cookie could be embedded into my session class (either the code above - or any other cookie encryption code). Should I replace the cookie which is automatically generated by PHP (PHPSESSID) or should generate a new cookie and encrypt this custom cookie? (My guess is the second is true, but I would like to be sure).</p> <p>How is the protection via encrypted cookies meant to work? I imagine the following attack: (1) if the attacker get somehow the cookie in his hand he just replies with the same cookie. Okay. he does not have the password but he has the encrypted password. Later I check only if the encrypted password is okay. So if the attacker has the cookie: game over - no matter if the cookie contains the password or "only" the encrypted password. Correct? (2) Okay this problem can be solved using a cyphered transmission like SSL. But then I think if I use SLL than the transmission is anyway cyphered. I don't need to cypher the password a second time using the encryption function. Correct?</p> <p>Here is the code for the session class I have already.</p> <p>Thanks</p> <pre><code>&lt;?php class SessionClass { private static $_instance; public static function getInstance() { if (!(self::$_instance instanceof self)) { self::$_instance = new self(); } return self::$_instance; } // getInstance public function __construct() { session_set_save_handler( array($this, "open"), array($this, "close"), array($this, "read"), array($this, "write"), array($this, "destroy"), array($this, "gc") ); $createTable = "CREATE TABLE IF NOT EXISTS `session`( ". "`sessionID` VARCHAR(128), ". "`data` MEDIUMBLOB, ". "`timestamp` INT, ". "`ip` VARCHAR(15), ". "PRIMARY KEY (`sessionID` ), ". "KEY (`timestamp`, `sessionID`))"; mysql_query($createTable); } // construct public function __destruct() { session_write_close(); } public function open ($path, $id) { // do nothing return (true); } public function close() { // do nothing return (true); } public function read($id) { $escapedID = mysql_escape_string($id); $query = sprintf("SELECT * FROM session WHERE sessionID = '%s'", $escapedID); $res = mysql_query($query); if ((!$res) || (!mysql_num_rows($res))) { $timestamp = time(); $query = sprintf("INSERT INTO session (sessionID, timestamp) VALUES ('%s', %s)", $escapedID, $timestamp); mysql_query($query); return ''; } elseif (($row = mysql_fetch_assoc($res))) { $query = "UPDATE session SET timestamp = "; $query .= time(); $query .= sprintf (" WHERE sessionID = '%s'", $escapedID); mysql_query($query); return $row['data']; } // elseif return ""; } // read public function write($id, $data) { $query = "REPLACE INTO session (sessionID, data, ip, timestamp) "; $query .= sprintf("VALUES ('%s', '%s', '%s', %s)", mysql_escape_string($id), mysql_escape_string($data), $_SERVER['REMOTE_ADDR'], time()); mysql_query($query); return (true); } // write public function destroy($id) { $escapedID = mysql_escape_string($id); $query = sprintf("DELETE FROM session WHERE sessionID = %s", $escapedID); $res = mysql_query($query); return (mysql_affected_rows($res) == 1); } // destroy public function gc($lifetime) { $query = "DELETE FROM session WHERE "; $query = sprintf("%s - timestamp &gt; %s", time(), $lifetime); mysql_query($query); return (true); } // gc } // SessionClass </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload