Last active
February 7, 2020 07:26
-
-
Save gaffling/67babe9ff0ed2b4ff75071c385859bdc to your computer and use it in GitHub Desktop.
[Session Wrapper] A simple Session Wrapper #php #class #session
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* --------------------------------------------------------------- */ | |
/* [Session Wrapper] A simple Session Wrapper #php #class #session */ | |
/* --------------------------------------------------------------- */ | |
include_once 'CustomException.php'; | |
if ( !class_exists('CustomException') ) { | |
class CustomException extends Exception {} | |
} | |
class SessionHandlerException extends CustomException {} | |
class SessionDisabledException extends SessionHandlerException {} | |
class InvalidArgumentTypeException extends SessionHandlerException {} | |
class ExpiredSessionException extends SessionHandlerException {} | |
class SessionCookieLifetimeException extends SessionHandlerException {} | |
class SessionUseOnlyCookiesException extends SessionHandlerException {} | |
class SessionCookieHttpOnlyException extends SessionHandlerException {} | |
class SessionCookieSecureException extends SessionHandlerException {} | |
class SessionHeaderAlreadySend extends SessionHandlerException {} | |
if ( !class_exists( 'session' ) ): | |
class session { | |
/** | |
* Session Age | |
* The number of seconds of inactivity before a session expires | |
* @var integer | |
*/ | |
protected static $SESSION_AGE = 1800; | |
/** | |
* __construct() | |
* class constructor starts the session | |
* | |
* @see https://stackoverflow.com/q/23576375 | |
* @return instance | |
*/ | |
function __construct() { | |
return $this->start(); | |
} | |
function __destruct() { | |
self::close(); | |
self::destroy(); | |
} | |
/** | |
* start() | |
* Initializes a new secure session or resumes an existing session | |
* | |
* @return boolean Returns true upon success and false upon failure | |
* @throws SessionDisabledException Sessions are disabled | |
* @throws SessionCookieLifetimeException | |
* @throws SessionUseOnlyCookiesException | |
* @throws SessionCookieHttpOnlyException | |
* @throws SessionCookieSecureException | |
*/ | |
public static function start() { | |
if ( function_exists('session_status') ) { | |
if ( session_status() == PHP_SESSION_DISABLED ) | |
throw new SessionDisabledException(); | |
} | |
if ( session_id() === '' ) { | |
$secure = true; | |
$httponly = true; | |
// better entropy source | |
if ( version_compare(phpversion(), '7.1.0', '<') ) { | |
ini_set('session.entropy_length', 20); | |
ini_set('session.entropy_file', '/dev/urandom'); | |
} | |
// specifies the lifetime of the cookie in seconds which is sent to the browser | |
// the value 0 means "until the browser is closed" | |
// smaller exploitation window for xss/csrf/clickjacking... | |
if ( ini_set('session.cookie_lifetime', 0) === false ) { | |
throw new SessionCookieLifetimeException(); | |
} | |
// Disallow session passing as a GET parameter | |
// Requires PHP 4.3.0 | |
// Prevents session fixation | |
if ( ini_set('session.use_only_cookies', 1) === false ) { | |
throw new SessionUseOnlyCookiesException(); | |
} | |
// Mark the cookie as accessible only through the HTTP protocol | |
// Requires PHP 5.2.0 | |
// Helps mitigate XSS | |
if ( ini_set('session.cookie_httponly', 1) === false ) { | |
throw new SessionCookieHttpOnlyException(); | |
} | |
// Ensure that session cookies are only sent using SSL | |
// Requires a properly installed SSL certificate | |
// Requires PHP 4.0.4 and HTTPS | |
// OWASP a9 Violations | |
if ( !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ) { | |
if ( ini_set('session.cookie_secure', 1) === false ) | |
throw new SessionCookieSecureException(); | |
} | |
$parameters = session_get_cookie_params(); | |
session_set_cookie_params($parameters['lifetime'], | |
$parameters['path'], $parameters['domain'], | |
$secure, $httponly | |
); | |
if ( headers_sent() ) | |
throw new SessionHeaderAlreadySend(); | |
return session_start(); | |
} | |
// Helps prevent hijacking by resetting the session ID at every request | |
// Might cause unnecessary file I/O overhead? | |
// TODO: create config variable to control regenerate ID behavior | |
return (!headers_sent()?session_regenerate_id(true):false); | |
} | |
/** | |
* set | |
* sets a var in global $_SESSION | |
* | |
* @param string $key key of var | |
* @param string $value value of var | |
* @return instance | |
* @throws InvalidArgumentTypeException Session key is not a string value | |
*/ | |
public static function set($key, $value) { | |
if ( !is_string($key) ) | |
throw new InvalidArgumentTypeException('Session key must be string value'); | |
self::start(); | |
self::_age(); | |
return $_SESSION[$key] = $value; | |
} | |
public static function s($key, $value) { | |
// Alias for session::set() | |
return self::set($key, $value); | |
} | |
public static function write($key, $value) { | |
// Alias for session::set() | |
return self::set($key, $value); | |
} | |
public static function w($key, $value) { | |
// Alias for session::set() | |
return self::set($key, $value); | |
} | |
/** | |
* get | |
* | |
* gets a var from global $_SESSION | |
* if key is not found it will return false | |
* | |
* @param string $key key of var to get | |
* @param string $secondKey second Key of value to return | |
* @return mixed | |
* @throws InvalidArgumentTypeException Session key is not a string value | |
*/ | |
public static function get($key, $child=false) { | |
if ( !is_string($key) ) | |
throw new InvalidArgumentTypeException('Session key must be string value'); | |
self::start(); | |
if ( isset($_SESSION[$key]) ) { | |
self::_age(); | |
if ( $child == false ) { | |
return $_SESSION[$key]; | |
} else { | |
if ( isset($_SESSION[$key][$child]) ) { | |
return $_SESSION[$key][$child]; | |
} | |
} | |
} | |
return false; | |
} | |
public static function g($key, $child = false) { | |
// Alias for session::get() | |
return self::get($key, $child); | |
} | |
public static function read($key, $child = false) { | |
// Alias for session::get() | |
return self::get($key, $child); | |
} | |
public static function r($key, $child = false) { | |
// Alias for session::get() | |
return self::get($key, $child); | |
} | |
/** | |
* del | |
* unsets a var in global $_SESSION | |
* | |
* @param string $key key of var to unset | |
* @throws InvalidArgumentTypeException Session key is not a string value | |
*/ | |
public static function del($key) { | |
if ( !is_string($key) ) | |
throw new InvalidArgumentTypeException('Session key must be string value'); | |
self::start(); | |
unset($_SESSION[$key]); | |
self::_age(); | |
} | |
public static function delete($key) { | |
// Alias for session::del() | |
self::start(); | |
return self::del($key); | |
} | |
/** | |
* close | |
* Closes the current session and releases session file lock | |
* | |
* @return boolean Returns true upon success and false upon failure | |
*/ | |
public static function close() { | |
if ( session_id() !== '' ) { | |
return session_write_close(); | |
} | |
return true; | |
} | |
/** | |
* destroy | |
* destroys the session | |
* | |
* @access public | |
*/ | |
public static function destroy() { | |
if ( session_id() !== '' ) { | |
session_reset(); | |
$_SESSION = array(); | |
// If it's desired to kill the session, also delete the session cookie | |
// Note: This will destroy the session, and not just the session data! | |
if ( ini_get("session.use_cookies") and !headers_sent() ) { | |
$parameters = session_get_cookie_params(); | |
setcookie(session_name(), '', time() - 42000, | |
$parameters["path"], $parameters["domain"], | |
$parameters["secure"], $parameters["httponly"] | |
); | |
} | |
session_unset(); | |
return session_destroy(); | |
} | |
} | |
/** | |
* parameters | |
* Returns current session cookie parameters or an empty array | |
* | |
* @return array Associative array of session cookie parameters | |
*/ | |
public static function parameters() { | |
#self::start(); | |
$return = array(); | |
if ( '' !== session_id() ){ | |
$return = session_get_cookie_params(); | |
} | |
return $return; | |
} | |
/** | |
* dump | |
* returns print_r version of session array with br tags | |
* | |
* @return string session array with br tag | |
*/ | |
public static function dump() { | |
self::start(); | |
return nl2br(print_r($_SESSION, true)); | |
} | |
/** | |
* _age | |
* Expires a session if it has been inactive for a specified amount of time | |
* | |
* @return void | |
* @throws ExpiredSessionException() when read or write is attempted on an expired session | |
*/ | |
private static function _age() { | |
$last = isset($_SESSION['LAST_ACTIVE']) ? $_SESSION['LAST_ACTIVE'] : false ; | |
if ( false !== $last && (time() - $last > self::$SESSION_AGE) ) { | |
self::destroy(); | |
throw new ExpiredSessionException(); | |
} | |
$_SESSION['LAST_ACTIVE'] = time(); | |
} | |
} | |
endif; | |
// TEST - HINT: Remember not to send header before you are ready with all session work! | |
$echo = '<pre>START<br>'; | |
$echo .= session::start(); | |
$echo .= '<br><br>SET<br>'; | |
$echo .= print_r(session::set('test2', array('name' => 'John Doe', 'number' => '4711')), true); | |
$echo .= '<br><br>DUMP<br>'; | |
$echo .= session::dump(); | |
$echo .= '<br><br>SET<br>'; | |
$echo .= session::set('dog', 'luke'); | |
$echo .= '<br><br>GET<br>'; | |
$echo .= session::get('dog'); | |
$echo .= '<br><br>PARAMETERS<br>'; | |
$echo .= print_r(session::parameters(), true); | |
$echo .= '<br><br>SET<br>'; | |
$echo .= session::set('cat', 'tequila'); | |
$echo .= '<br><br>GET<br>'; | |
$echo .= session::get('dog'); | |
$echo .= '<br><br>GET<br>'; | |
$echo .= session::get('cat'); | |
$echo .= '<br><br>DESTROY<br>'; | |
$echo .= session::destroy(); | |
$echo .= '<br><br>CLOSE<br>'; | |
$echo .= session::close(); | |
$echo .= '<br><br>DUMP<br>'; | |
$echo .= session::dump(); | |
echo $echo; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment