I'm yet to add garbage cleanup, ID regeneration and the ability to unset sessions, but this is what I have so far.
- Does this help prevent session hijacking/fixation?
- Can you see any vulnerabilities?
index.php
require 'Session.class.php';
// I know this isn't done very well
$pdo = new PDO('mysql:host=localhost;dbname=session', 'root', 'root');
$session = new Session($pdo);
$session->set(array(
'username' => 'hello'
));
echo $session->get('username');
Session.class.php
<?php
class Session {
private $_db = null;
private $_expiry = 7200;
private $_id;
private $_data = array();
public function __construct(PDO $db) {
$this->_db = $db;
$this->_run();
if (mt_rand(0, 10) <= 8) $this->_garbageCleanup();
}
public function get($key) {
return isset($this->_data[$key]) ? $this->_data[$key] : FALSE;
}
public function set($data = array()) {
$this->_data = array_merge($data, $this->_data);
$query = $this->_db->prepare("UPDATE `sessions` SET `session_data` = ? WHERE `session_id` = ?");
$query->bindValue(1, serialize($this->_data));
$query->bindValue(2, $this->_id);
$query->execute();
}
private function _run() {
if (isset($_COOKIE['session'])) {
$this->_id = $_COOKIE['session'];
$query = $this->_db->prepare("SELECT * FROM `sessions` WHERE `session_id` = ? AND `session_ip` = ? AND `session_user_agent` = ?");
$query->bindValue(1, $this->_id);
$query->bindValue(2, $_SERVER['REMOTE_ADDR']);
$query->bindValue(3, $_SERVER['HTTP_USER_AGENT']);
$query->execute();
$result = $query->fetch();
$this->_data = unserialize($result['session_data']);
} else {
$this->_createSession();
}
}
private function _createSession() {
$this->_id = md5(microtime() . mt_rand(0, 100));
$query = $this->_db->prepare("INSERT INTO `sessions` VALUES (?, ?, ?, ?)");
$query->bindValue(1, $this->_id);
$query->bindValue(2, serialize($this->_data));
$query->bindValue(3, $_SERVER['REMOTE_ADDR']);
$query->bindValue(4, $_SERVER['HTTP_USER_AGENT']);
$query->execute();
setcookie('session', $this->_id, time() + $this->_expiry);
}
private function garbageCleanup() {
// Does nothing yet, but will later!
}
}