示例#1
0
 /**
  * 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 saveSession($oSession, $bCreateSessionIfNotExists = false)
 {
     $sSessionId = $oSession->getId();
     if ($oSession->isLoggedIn()) {
         //purge the old sessions from database (needed for the update/insert test)
         $this->purgeExpiredSessionsFromDatabase();
         //try to update session in database (if it already exists)
         $sSessionIdentifier = AnwEnv::calculateSessionIdentifier();
         $sSessionCode = self::generateSessionCode();
         //a new code is generated (even if session already exists) to prevent session stealing
         $nSessionUser = $oSession->getUser()->getId();
         $sSessionResume = $oSession->isResume() ? 1 : 0;
         $nSessionTimeSeen = time();
         $asData = array("SessionIdentifier" => $this->db()->strtosql($sSessionIdentifier), "SessionCode" => $this->db()->strtosql($sSessionCode), "SessionUser" => $this->db()->inttosql($nSessionUser), "SessionResume" => $this->db()->strtosql($sSessionResume), "SessionTimeSeen" => $this->db()->inttosql($nSessionTimeSeen));
         $this->db()->do_update($asData, "session", "WHERE SessionId=" . $this->db()->strtosql($sSessionId));
         //otherwise, we may need to INSERT this new session or to kill it
         if ($this->db()->affected_rows() != 1) {
             if ($bCreateSessionIfNotExists) {
                 //user is logging in, it's normal that the session doesn't exist in database.
                 $asData["SessionId"] = $this->db()->strtosql($sSessionId);
                 $asData["SessionTimeStart"] = $this->db()->inttosql(time());
                 $asData["SessionTimeAuth"] = $this->db()->inttosql(time());
                 $this->db()->do_insert($asData, "session");
             } else {
                 //here, the session is supposed to exist in database, but isn't found.
                 //this can happend in the following situations:
                 // - The session has expired (DurationIdle or DurationMax)
                 // - An user was using a session, when someone tried to steal it. The session was killed for security reasons.
                 // - An administrator has killed the session.
                 // - The session has expired.
                 //In both situations, the current session is no longer safe and must be closed.
                 self::debug("WARNING: Session doesn't exist in database, but session creation is NOT expected. Logging out.");
                 AnwCurrentSession::logout();
                 return;
             }
         }
         //remember current session in cookies
         $nCookieExpires = AnwSessions::isResumeEnabled() && $oSession->isResume() ? time() + $this->cfgResumeDelayMax() : 0;
         AnwEnv::putCookie(self::COOKIE_SESSION_ID, $sSessionId, $nCookieExpires);
         AnwEnv::putCookie(self::COOKIE_SESSION_CODE, $sSessionCode, $nCookieExpires);
         AnwEnv::putSession(self::SESSION_CODE, $sSessionCode);
     } else {
         //unset cookies
         AnwEnv::unsetCookie(self::COOKIE_SESSION_ID);
         AnwEnv::unsetCookie(self::COOKIE_SESSION_CODE);
     }
 }