public static function init() { $name = Configure::read('Session.cookie'); $level = Configure::read('Security.level'); $timeout = Configure::read('Session.timeout'); self::$timeout = $timeout * Security::inactiveMins(); self::$prefix = $name; if ($level == 'high') { $cookieLifeTime = 0; } else { $cookieLifeTime = Configure::read('Session.timeout') * (Security::inactiveMins() * 60); } if (empty($_SESSION)) { if (function_exists('ini_set')) { ini_set('session.use_trans_sid', 0); ini_set('url_rewriter.tags', ''); ini_set('session.save_handler', 'user'); ini_set('session.serialize_handler', 'php'); ini_set('session.use_cookies', 1); ini_set('session.name', $name); ini_set('session.cookie_lifetime', $cookieLifeTime); ini_set('session.cookie_path', '/'); ini_set('session.auto_start', 0); } } session_set_save_handler(array('RedisSession', '__open'), array('RedisSession', '__close'), array('RedisSession', '__read'), array('RedisSession', '__write'), array('RedisSession', '__destroy'), array('RedisSession', '__gc')); }
/** * testInactiveMins method * * @access public * @return void */ function testInactiveMins() { Configure::write('Security.level', 'high'); $this->assertEqual(10, Security::inactiveMins()); Configure::write('Security.level', 'medium'); $this->assertEqual(100, Security::inactiveMins()); Configure::write('Security.level', 'low'); $this->assertEqual(300, Security::inactiveMins()); }
/** * OPEN * - Connect to Redis * - Calculate and set timeout for SETEX * - Set session_name as key prefix * * @access public * @return boolean true */ public function open() { $this->settings = array_merge(array('engine' => 'Redis', 'prefix' => Inflector::slug(basename(dirname(dirname(APP)))) . '_session_'), Configure::read('Session')); $this->timeout = Configure::read('Session.timeout') * Security::inactiveMins(); $this->redis = new Redis(); $this->redis->pconnect($this->settings['hostname'], $this->settings['port']); $this->redis->setOption(Redis::OPT_PREFIX, $this->settings['prefix']); if (defined('Redis::SERIALIZER_IGBINARY')) { $this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY); } else { $this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP); } return true; }
/** * Helper function called on write for database sessions. * * @param integer $id ID that uniquely identifies session in database * @param mixed $data The value of the data to be saved. * @return boolean True for successful write, false otherwise. * @access private */ public function __write($id, $data) { if (!$id) { return false; } // create expires $expiry = time() + Configure::read('Session.timeout') * Security::inactiveMins(); // create new session data $new_obj = array('data' => $data, 'lock' => 0, 'active' => 1, 'expiry' => $expiry); // check for existing session for merge if (!empty($this->_session)) { $obj = (array) $this->_session; $new_obj = array_merge($obj, $new_obj); } // atomic update $query = array('session_id' => $id); // update options $options = array('upsert' => TRUE, 'safe' => TRUE, 'fsync' => TRUE); // perform the update or insert try { $result = $this->_mongo->update($query, array('$set' => $new_obj), $options); return $result['ok'] == 1; } catch (Exception $e) { return false; } return true; }
/** * Add authentication key for new form posts * * @param object $controller Instantiating controller * @return bool Success * @access private */ function __generateToken(&$controller) { if (!isset($controller->params['requested']) || $controller->params['requested'] != 1) { $authKey = Security::generateAuthKey(); $expires = strtotime('+' . Security::inactiveMins() . ' minutes'); $token = array('key' => $authKey, 'expires' => $expires, 'allowedControllers' => $this->allowedControllers, 'allowedActions' => $this->allowedActions, 'disabledFields' => $this->disabledFields); if (!isset($controller->data)) { $controller->data = array(); } if ($this->Session->check('_Token')) { $tData = unserialize($this->Session->read('_Token')); if (isset($tData['expires']) && $tData['expires'] > time() && isset($tData['key'])) { $token['key'] = $tData['key']; } } $controller->params['_Token'] = $token; $this->Session->write('_Token', serialize($token)); } return true; }
/** * Helper function called on write for database sessions. * * @param integer $id ID that uniquely identifies session in database * @param mixed $data The value of the the data to be saved. * @return boolean True for successful write, false otherwise. * @access private */ function __write($id, $data) { $expires = time() + Configure::read('Session.timeout') * Security::inactiveMins(); $model =& ClassRegistry::getObject('Session'); $return = $model->save(compact('id', 'data', 'expires')); return $return; }
/** * Helper function called on write for database sessions. * * @param integer $id ID that uniquely identifies session in database * @param mixed $data The value of the data to be saved. * @return boolean True for successful write, false otherwise. * @access private */ function __write($id, $data) { if (!$id) { return false; } $expires = time() + Configure::read('Session.timeout') * Security::inactiveMins(); $model =& ClassRegistry::getObject('Session'); $return = $model->save(array($model->primaryKey => $id) + compact('data', 'expires')); return $return; }
/** * Helper method to create a new session. * * @return void * @access protected */ function _checkValid() { if ($this->read('Config')) { if ((Configure::read('Session.checkAgent') === false || $this->_userAgent == $this->read('Config.userAgent')) && $this->time <= $this->read('Config.time')) { $time = $this->read('Config.time'); $this->write('Config.time', $this->sessionTime); if (Configure::read('Security.level') === 'high') { $check = $this->read('Config.timeout'); $check = $check - 1; $this->write('Config.timeout', $check); if (time() > $time - Security::inactiveMins() * Configure::read('Session.timeout') + 2 || $check < 1) { $this->renew(); $this->write('Config.timeout', 10); } } $this->valid = true; } else { $this->destroy(); $this->valid = false; $this->__setError(1, 'Session Highjacking Attempted !!!'); } } else { $this->write('Config.userAgent', $this->_userAgent); $this->write('Config.time', $this->sessionTime); $this->write('Config.timeout', 10); $this->valid = true; $this->__setError(1, 'Session is valid'); } }
/** * Constructor. * * @param string $base The base path for the Session * @param boolean $start Should session be started right now * @access public */ function __construct($base = null, $start = true) { if (env('HTTP_USER_AGENT') != null) { $this->_userAgent = md5(env('HTTP_USER_AGENT') . CAKE_SESSION_STRING); } else { $this->_userAgent = ""; } $this->time = time(); if ($start === true) { $this->host = env('HTTP_HOST'); if (empty($base) || strpos($base, '?')) { $this->path = '/'; } else { $this->path = $base; } if (strpos($this->host, ':') !== false) { $this->host = substr($this->host, 0, strpos($this->host, ':')); } $this->sessionTime = $this->time + Security::inactiveMins() * CAKE_SESSION_TIMEOUT; $this->security = CAKE_SECURITY; if (function_exists('session_write_close')) { session_write_close(); } $this->__initSession(); session_cache_limiter("must-revalidate"); session_start(); header('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"'); $this->__checkValid(); } parent::__construct(); }
/** * Component startup. All security checking happens here. * * @param object $controller * @return unknown * @access public */ function startup(&$controller) { if (is_array($this->requirePost) && !empty($this->requirePost)) { if (in_array($controller->action, $this->requirePost)) { if (!$this->RequestHandler->isPost()) { if (!$this->blackHole($controller)) { return null; } } } } if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($controller->params['form'])) { if (in_array($controller->action, $this->requireAuth)) { if (!isset($controller->params['data']['_Token'])) { if (!$this->blackHole($controller)) { return null; } } $token = $controller->params['data']['_Token']['key']; if ($this->Session->check('_Token')) { $tData = $this->Session->read('_Token'); if (!(intval($tData['expires']) > strtotime('now')) || $tData['key'] !== $token) { if (!$this->blackHole($controller)) { return null; } } if (!empty($tData['allowedControllers']) && !in_array($controller->params['controller'], $tData['allowedControllers']) || !empty($tData['allowedActions']) && !in_array($controller->params['action'], $tData['allowedActions'])) { if (!$this->blackHole($controller)) { return null; } } } else { if (!$this->blackHole($controller)) { return null; } } } } if (!isset($controller->params['requested']) || $controller->params['requested'] != 1) { // Add auth key for new form posts $authKey = Security::generateAuthKey(); $expires = strtotime('+' . Security::inactiveMins() . ' minutes'); $token = array('key' => $authKey, 'expires' => $expires, 'allowedControllers' => $this->allowedControllers, 'allowedActions' => $this->allowedActions); if (!isset($controller->params['data'])) { $controller->params['data'] = array(); } $controller->params['_Token'] = $token; $this->Session->write('_Token', $token); } }
/** * testSessionTimeout method * * @access public * @return void */ function testSessionTimeout() { Configure::write('debug', 2); Configure::write('Security.level', 'low'); session_destroy(); $Session =& new SessionComponent(); $Session->destroy(); $Session->write('Test', 'some value'); $this->assertEqual($Session->sessionTime, time() + (300 * Configure::read('Session.timeout'))); $this->assertEqual($_SESSION['Config']['timeout'], 10); $this->assertEqual($_SESSION['Config']['time'], $Session->sessionTime); $this->assertEqual($Session->time, time()); $this->assertEqual($_SESSION['Config']['time'], $Session->time + (300 * Configure::read('Session.timeout'))); Configure::write('Security.level', 'medium'); $Session =& new SessionComponent(); $Session->destroy(); $Session->write('Test', 'some value'); $this->assertEqual($Session->sessionTime, mktime() + (100 * Configure::read('Session.timeout'))); $this->assertEqual($_SESSION['Config']['timeout'], 10); $this->assertEqual($_SESSION['Config']['time'], $Session->sessionTime); $this->assertEqual($Session->time, time()); $this->assertEqual($_SESSION['Config']['time'], $Session->time + (Security::inactiveMins() * Configure::read('Session.timeout'))); Configure::write('Security.level', 'high'); $Session =& new SessionComponent(); $Session->destroy(); $Session->write('Test', 'some value'); $this->assertEqual($Session->sessionTime, time() + (10 * Configure::read('Session.timeout'))); $this->assertEqual($_SESSION['Config']['timeout'], 10); $this->assertEqual($_SESSION['Config']['time'], $Session->sessionTime); $this->assertEqual($Session->time, time()); $this->assertEqual($_SESSION['Config']['time'], $Session->time + (Security::inactiveMins() * Configure::read('Session.timeout'))); }
/** * Constructor. * * @param string $base The base path for the Session * @param boolean $start Should session be started right now * @access public */ function __construct($base = null, $start = true) { if (Configure::read('Session.save') === 'database' && !class_exists('ConnectionManager')) { uses('model' . DS . 'connection_manager'); } if (Configure::read('Session.checkAgent') === true) { if (env('HTTP_USER_AGENT') != null) { $this->_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt')); } } $this->time = time(); if ($start === true) { $this->host = env('HTTP_HOST'); if (empty($base) || strpos($base, '?' || strpos($base, 'index.php'))) { $this->path = '/'; } else { $this->path = $base; } if (strpos($this->host, ':') !== false) { $this->host = substr($this->host, 0, strpos($this->host, ':')); } if (!class_exists('Security')) { uses('security'); } $this->sessionTime = $this->time + Security::inactiveMins() * Configure::read('Session.timeout'); $this->security = Configure::read('Security.level'); if (function_exists('session_write_close')) { session_write_close(); } $this->__initSession(); $this->__startSession(); $this->__checkValid(); } parent::__construct(); }
/** * Helper method to create a new session. * * @access protected */ function _checkValid() { if ($this->read('Config')) { if (Configure::read('Session.checkAgent') === false || $this->_userAgent == $this->read("Config.userAgent") && $this->time <= $this->read("Config.time")) { $time = $this->read("Config.time"); $this->write("Config.time", $this->sessionTime); if ($this->security === 'high') { $check = $this->read("Config.timeout"); $check = $check - 1; $this->write("Config.timeout", $check); if (time() > $time - Security::inactiveMins() * CAKE_SESSION_TIMEOUT + 2 || $check < 1) { $this->renew(); $this->write('Config.timeout', 10); } } $this->valid = true; } else { $this->destroy(); $this->valid = false; $this->__setError(1, "Session Highjacking Attempted !!!"); } } else { srand((double) microtime() * 1000000); $this->write("Config.userAgent", $this->_userAgent); $this->write("Config.time", $this->sessionTime); $this->write('Config.rand', rand()); $this->write('Config.timeout', 10); $this->valid = true; $this->__setError(1, "Session is valid"); } }