Skip to content

Instantly share code, notes, and snippets.

@gaffling
Last active February 7, 2020 07:26
Show Gist options
  • Save gaffling/67babe9ff0ed2b4ff75071c385859bdc to your computer and use it in GitHub Desktop.
Save gaffling/67babe9ff0ed2b4ff75071c385859bdc to your computer and use it in GitHub Desktop.
[Session Wrapper] A simple Session Wrapper #php #class #session
<?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