pics/models/Session.php

90 lines
3.6 KiB
PHP
Raw Permalink Normal View History

<?php
/*****************************************************************************
* Session.php
* Contains the key class Session.
*
* Kabuki CMS (C) 2013-2015, Aaron van Geffen
*****************************************************************************/
class Session
{
public static function start()
{
session_start();
// Resuming an existing session? Check what we know!
if (isset($_SESSION['user_id'], $_SESSION['ip_address'], $_SESSION['user_agent']))
{
// If we're not browsing over HTTPS, protect against session hijacking.
if (!isset($_SERVER['HTTPS']) && isset($_SERVER['REMOTE_ADDR']) && $_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR'])
{
$_SESSION = [];
throw new UserFacingException('Your session failed to validate: your IP address has changed. Please re-login and try again.');
}
// Either way, require re-login if the browser identifier has changed.
elseif (isset($_SERVER['HTTP_USER_AGENT']) && $_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT'])
{
$_SESSION = [];
throw new UserFacingException('Your session failed to validate: your browser identifier has changed. Please re-login and try again.');
}
}
elseif (!isset($_SESSION['ip_address'], $_SESSION['user_agent']))
$_SESSION = [
'ip_address' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '',
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '',
];
return true;
}
public static function resetSessionToken()
{
$_SESSION['session_token'] = sha1(session_id() . mt_rand());
$_SESSION['session_token_key'] = substr(preg_replace('~^\d+~', '', sha1(mt_rand() . session_id() . mt_rand())), 0, rand(7, 12));
return true;
}
public static function validateSession($method = 'post')
{
// First, check whether the submitted token and key match the ones in storage.
if (($method === 'post' && (!isset($_POST[$_SESSION['session_token_key']]) || $_POST[$_SESSION['session_token_key']] !== $_SESSION['session_token'])) ||
($method === 'get' && (!isset($_GET[$_SESSION['session_token_key']]) || $_GET[$_SESSION['session_token_key']] !== $_SESSION['session_token'])))
throw new UserFacingException('Session failed to verify (' . $method . '). Please reload the page and try again.');
// Check the referring site, too -- should be the same site!
$referring_host = isset($_SERVER['HTTP_REFERER']) ? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) : '';
if (!empty($referring_host))
{
if (strpos($_SERVER['HTTP_HOST'], ':') !== false)
$current_host = substr($_SERVER['HTTP_HOST'], 0, strpos($_SERVER['HTTP_HOST'], ':'));
else
$current_host = $_SERVER['HTTP_HOST'];
$base_url_host = parse_url(BASEURL, PHP_URL_HOST);
// The referring_host must match either the base_url_host or the current_host.
if (strtolower($referring_host) !== strtolower($base_url_host) && strtolower($referring_host) !== strtolower($current_host))
throw new UserFacingException('Invalid referring URL. Please reload the page and try again.');
}
// All looks good from here! But you can only use this token once, so...
return self::resetSessionToken();
}
public static function getSessionToken()
{
if (empty($_SESSION['session_token']))
trigger_error('Call to getSessionToken without a session token being set!', E_USER_ERROR);
return $_SESSION['session_token'];
}
public static function getSessionTokenKey()
{
if (empty($_SESSION['session_token_key']))
trigger_error('Call to getSessionTokenKey without a session token key being set!', E_USER_ERROR);
return $_SESSION['session_token_key'];
}
}