Hallo,
Ik maak gebruik van een custom session object om sessie te implementeren. De code is gebaseerd op How to Create a Secure Session Management System in PHP and MySQL
De code werk zonder problemen in php v 5.x, in php v7 is er een probleem met het vernieuwen van de id van de sessie ( session_regenerate_id(true); )
De standaard workarounds (zoals dat door gewijzigd gedrag geen waarde een lege string moeten doorgegeven worden door een strengere typecasting van v7 zijn uiteraard reeds toegepast)
Iemand enig idee wat er mis is ?
De klasse is de volgende:
<?php
class session {
function __construct() {
// set our custom session functions.
session_set_save_handler(array($this, 'open'), array($this, 'close'), array($this, 'read'), array($this, 'write'), array($this, 'destroy'), array($this, 'gc'));
// This line prevents unexpected effects when using objects as save handlers.
register_shutdown_function('session_write_close');
}
function start_session($session_name, $secure) {
// Make sure the session cookie is not accessable via javascript.
$httponly = true;
// Hash algorithm to use for the sessionid. (use hash_algos() to get a list of available hashes.)
$session_hash = 'sha512';
// Check if hash is available
if (in_array($session_hash, hash_algos())) {
// Set the has function.
ini_set('session.hash_function', $session_hash);
}
// How many bits per character of the hash.
// The possible values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ",").
ini_set('session.hash_bits_per_character', 5);
// Force the session to only use cookies, not URL variables.
ini_set('session.use_only_cookies', 1);
// Get session cookie parameters
$cookieParams = session_get_cookie_params();
// Set the parameters
session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly);
// Change the session name
session_name($session_name);
// Now we cat start the session
try
{
// This line regenerates the session and delete the old one.
// It also generates a new encryption key in the database.
session_start();
session_regenerate_id(true);
/* $new_session_id = session_id();
echo "old_session_id:{$old_session_id} " . "<br>\r\n";
echo "new_session_id:{$new_session_id}<br>\r\n";
echo "<br>\r\n";
*/
}
catch(Throwable $t)
{
echo $t->getMessage();
exit;
}
}
function open() {
$host = '***';
$user = '***';
$pass = '***';
$name = '***';
$mysqli = new mysqli($host, $user, $pass, $name);
$this->db = $mysqli;
return true;
}
function close() {
$this->db->close();
return true;
}
function read($id) {
if(!isset($this->read_stmt)) {
$this->read_stmt = $this->db->prepare("SELECT data FROM tblSessies WHERE id = ? LIMIT 1");
}
$this->read_stmt->bind_param('s', $id);
$this->read_stmt->execute();
$this->read_stmt->store_result();
$this->read_stmt->bind_result($data);
$this->read_stmt->fetch();
$key = $this->getkey($id);
$data = $this->decrypt($data, $key);
if($data == null) return "";
return (string) $data;
}
function write($id, $data) {
// Get unique key
$key = $this->getkey($id);
// Encrypt the data
$data = $this->encrypt($data, $key);
$time = time();
if(!isset($this->w_stmt)) {
$this->w_stmt = $this->db->prepare("REPLACE INTO tblSessies (id, set_time, data, session_key) VALUES (?, ?, ?, ?)");
}
$this->w_stmt->bind_param('siss', $id, $time, $data, $key);
$this->w_stmt->execute();
return true;
}
function destroy($id) {
if(!isset($this->delete_stmt)) {
$this->delete_stmt = $this->db->prepare("DELETE FROM tblSessies WHERE id = ?");
}
$this->delete_stmt->bind_param('s', $id);
$this->delete_stmt->execute();
return true;
}
function gc($max) {
if(!isset($this->gc_stmt)) {
$this->gc_stmt = $this->db->prepare("DELETE FROM tblSessies WHERE set_time < ?");
}
$old = time() - $max;
$this->gc_stmt->bind_param('s', $old);
$this->gc_stmt->execute();
return true;
}
private function getkey($id) {
if(!isset($this->key_stmt)) {
$this->key_stmt = $this->db->prepare("SELECT session_key FROM tblSessies WHERE id = ? LIMIT 1");
}
$this->key_stmt->bind_param('s', $id);
$this->key_stmt->execute();
$this->key_stmt->store_result();
if($this->key_stmt->num_rows == 1) {
$this->key_stmt->bind_result($key);
$this->key_stmt->fetch();
return (string) $key;
} else {
$random_key = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
return (string) $random_key;
}
}
private function encrypt($data, $key) {
$salt = '*** some salt ***';
$key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv));
return (string)$encrypted;
}
private function decrypt($data, $key) {
$salt = '*** some salt ***';
$key = substr(hash('sha256', $salt.$key.$salt), 0, 32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB, $iv);
return (string)$decrypted;
}
function login($email, $password) {
if ($stmt = $this->db->prepare("SELECT id, username, password, salt FROM tblGebruikers WHERE email = ? LIMIT 1"))
{
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $username, $db_password, $salt);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
//echo "$password\n<br>";
if ($stmt->num_rows == 1)
{
// If the user exists we check if the account is locked
// from too many login attempts
if ($this->checkbrute($user_id) == true)
{
// Account is locked
// Send an email to user saying their account is locked
return false;
} else
{
// Check if the password in the database matches
// the password the user submitted.
if ($db_password == $password) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['userid'] = $user_id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512',
$password . $user_browser);
// Login successful.
return true;
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
$this->db->query("INSERT INTO tblAanmeldingen(`user_id`, `tijdstip`) VALUES ('$user_id', '$now')");
return false;
}
}
}
else
{
// No user exists.
return false;
}
}
return false;
}
private function checkbrute($user_id)
{
// Get timestamp of current time
$now = time();
// All login attempts are counted from the past 2 hours.
$valid_attempts = $now - (2 * 60 * 60);
if ($stmt = $this->db->prepare("SELECT tijdstip
FROM tblAanmeldingen
WHERE user_id = ? AND tijdstip > '$valid_attempts'")) {
$stmt->bind_param('i', $user_id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there have been more than 5 failed logins
if ($stmt->num_rows > 5) {
return true;
} else {
return false;
}
}
return true;
}
function userLoggedIn()
{
// Check if all session variables are set
if (isset($_SESSION['userid'], $_SESSION['username'], $_SESSION['login_string']))
{
$user_id = $_SESSION['userid'];
$login_string = $_SESSION['login_string'];
$username = $_SESSION['username'];
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
if ($stmt = $this->db->prepare("SELECT password FROM tblGebruikers WHERE id = ? LIMIT 1"))
{
// Bind "$user_id" to parameter.
$stmt->bind_param('i', $user_id);
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
if ($stmt->num_rows == 1)
{
// If the user exists get variables from result.
$stmt->bind_result($password);
$stmt->fetch();
$login_check = hash('sha512', $password . $user_browser);
if ($login_check == $login_string) {
// Logged In!!!!
return true;
}
else
{
// Not logged in
return false;
}
}
else
{
// Not logged in
return false;
}
}
else
{
// Not logged in
return false;
}
}
else
{
// Not logged in
return false;
}
return false;
}
}
?>
3.604 views