/** * Initialize PHP session and do security checks to prevent session stealing. */ private static function initPHPSession() { //start PHP session session_write_close(); session_start(); self::debug("initPHPSession: PHPSESSID=" . session_id()); //1. check client's identifier code //we make sure that who created the session is the one who resumes it. $sSessionIdentifier = self::calculateSessionIdentifier(); if (AnwEnv::_SESSION(self::PHPSESSION_IDENTIFIER) && $sSessionIdentifier == AnwEnv::_SESSION(self::PHPSESSION_IDENTIFIER)) { //2. check session code //just to make it harder, even if someone who steals PHPSESSID would probably steal the session code too. if (AnwEnv::_SESSION(self::PHPSESSION_CODE) && AnwEnv::_COOKIE(self::COOKIE_PHPSESSION_CODE) && AnwEnv::_SESSION(self::PHPSESSION_CODE) == AnwEnv::_COOKIE(self::COOKIE_PHPSESSION_CODE)) { //allright, session seems safe to work with self::debug("initPHPSession: OK, resuming PHP session (" . session_id() . ")"); return; } else { self::debug("initPHPSession: WARNING: no valid PHP session: bad session code"); } } else { self::debug("initPHPSession: no valid PHP session: bad or missing session identifier"); } //no valid session found self::debug("initPHPSession: no valid PHP session found, starting a new session (" . session_id() . ")"); //clear session data if (is_array($_SESSION)) { foreach ($_SESSION as $i => $v) { AnwEnv::unsetSession($i); } } //start a new session and delete old phpsession file session_regenerate_id(true); //set the session identifier, for next hit AnwEnv::putSession(self::PHPSESSION_IDENTIFIER, $sSessionIdentifier); //generate a session code $sSessionCode = self::generateSessionCode(); AnwEnv::putCookie(self::COOKIE_PHPSESSION_CODE, $sSessionCode); AnwEnv::putSession(self::PHPSESSION_CODE, $sSessionCode); }
private function getCurrentSessionFromDatabase() { $sCookieSessionId = AnwEnv::_COOKIE(self::COOKIE_SESSION_ID); $sCookieSessionCode = AnwEnv::_COOKIE(self::COOKIE_SESSION_CODE); if ($sCookieSessionId && $sCookieSessionCode) { //first of all, purge the old sessions from database $this->purgeExpiredSessionsFromDatabase(); //we have session info in cookies, check against the database self::debug("Session info found in cookies, checking against database..."); $q = $this->db()->query("SELECT SessionCode, SessionIdentifier, " . "SessionUser, SessionResume, " . "SessionTimeStart, SessionTimeSeen, SessionTimeAuth " . "FROM `#PFX#session` WHERE SessionId=" . $this->db()->strtosql($sCookieSessionId) . " " . "LIMIT 1"); $oData = $this->db()->fto($q); $this->db()->free($q); if ($oData) { self::debug("Session found in database"); //check session code if ($sCookieSessionCode == $oData->SessionCode) { self::debug("Session code OK"); if ($sCookieSessionCode != AnwEnv::_SESSION(self::SESSION_CODE)) { //_SESSION may contain an old session code when running multiple Anwiki instances synchronized together //update _SESSION as session is valid! self::debug("Session code is outdated in the session, resynchronizing it with the cookie..."); AnwEnv::putSession(self::SESSION_CODE, $sCookieSessionCode); } //check session identifier if (AnwEnv::calculateSessionIdentifier() == $oData->SessionIdentifier) { self::debug("Session identifier OK"); //check that session user still exists $nSessionUserId = $oData->SessionUser; $oSessionUser = AnwUsers::getUser($nSessionUserId); if ($oSessionUser->exists()) { //allright, restore the session $bSessionResume = $oData->SessionResume == '1' ? true : false; $sSessionLang = $oSessionUser->getLang(); $nSessionTimezone = $oSessionUser->getTimezone(); $nSessionTimeStart = $oData->SessionTimeStart; $nSessionTimeSeen = $oData->SessionTimeSeen; $nSessionTimeAuth = $oData->SessionTimeAuth; $oSession = AnwSession::rebuildSession($oSessionUser, $bSessionResume, $sSessionLang, $nSessionTimezone, $sCookieSessionId, $nSessionTimeStart, $nSessionTimeSeen, $nSessionTimeAuth); return $oSession; } else { self::debug("Session user doesn't exist anymore"); } } else { self::debug("Invalid session identifier"); } } else { self::debug("Invalid session code"); } //here, the sessionid was found but a bad sessioncode, sessionidentifier or user was given //we kill the session to prevent hacking attempts self::debug("WARNING: sessionid was found, but wrong sessions checks was provided. Kill the session."); $this->db()->query("DELETE FROM `#PFX#session` WHERE SessionId=" . $this->db()->strtosql($sCookieSessionId)); } else { self::debug("Session NOT found in database"); } } throw new AnwSessionNotFoundException(); }