Skip to content

Commit

Permalink
Merge pull request apereo#258 from apereo/hash_ticket_for_session_id_…
Browse files Browse the repository at this point in the history
…with_salt

Hash ticket for session id with salt. Fix apereo#224, Fix apereo#244, Fix apereo#248.
  • Loading branch information
adamfranco authored Mar 15, 2018
2 parents 62e5185 + 96b7d6b commit 7a949de
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
21 changes: 21 additions & 0 deletions source/CAS.php
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,27 @@ public static function setExtraCurlOption($key, $value)
phpCAS :: traceEnd();
}

/**
* Set a salt/seed for the session-id hash to make it harder to guess.
*
* When $changeSessionID = true phpCAS will create a session-id that is derived
* from the service ticket. Doing so allows phpCAS to look-up and destroy the
* proper session on single-log-out requests. While the service tickets
* provided by the CAS server may include enough data to generate a strong
* hash, clients may provide an additional salt to ensure that session ids
* are not guessable if the session tickets do not have enough entropy.
*
* @param string $salt The salt to combine with the session ticket.
*
* @return void
*/
public static function setSessionIdSalt($salt) {
phpCAS :: traceBegin();
phpCAS::_validateClientExists();
self::$_PHPCAS_CLIENT->setSessionIdSalt($salt);
phpCAS :: traceEnd();
}

/**
* If you want your service to be proxied you have to enable it (default
* disabled) and define an accepable list of proxies that are allowed to
Expand Down
39 changes: 37 additions & 2 deletions source/CAS/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -1808,7 +1808,7 @@ public function handleLogoutRequests($check_client=true, $allowed_clients=false)
// If phpCAS is managing the session_id, destroy session thanks to
// session_id.
if ($this->getChangeSessionID()) {
$session_id = preg_replace('/[^a-zA-Z0-9\-]/', '', $ticket2logout);
$session_id = $this->_sessionIdForTicket($ticket2logout);
phpCAS::trace("Session id: ".$session_id);

// destroy a possible application session created before phpcas
Expand Down Expand Up @@ -3682,7 +3682,7 @@ private function _renameSession($ticket)
phpCAS :: trace("Killing session: ". session_id());
session_destroy();
// set up a new session, of name based on the ticket
$session_id = preg_replace('/[^a-zA-Z0-9\-]/', '', $ticket);
$session_id = $this->_sessionIdForTicket($ticket);
phpCAS :: trace("Starting session: ". $session_id);
session_id($session_id);
session_start();
Expand All @@ -3701,6 +3701,41 @@ private function _renameSession($ticket)
phpCAS::traceEnd();
}

/**
* Answer a valid session-id given a CAS ticket.
*
* The output must be deterministic to allow single-log-out when presented with
* the ticket to log-out.
*
*
* @param string $ticket name of the ticket
*
* @return string
*/
private function _sessionIdForTicket($ticket)
{
// Hash the ticket to ensure that the value meets the PHP 7.1 requirement
// that session-ids have a length between 22 and 256 characters.
return hash('sha256', $this->_sessionIdSalt . $ticket);
}

/**
* Set a salt/seed for the session-id hash to make it harder to guess.
*
* @var string $_sessionIdSalt
*/
private $_sessionIdSalt = '';

/**
* Set a salt/seed for the session-id hash to make it harder to guess.
*
* @param string $salt
*
* @return void
*/
public function setSessionIdSalt($salt) {
$this->_sessionIdSalt = (string)$salt;
}

// ########################################################################
// AUTHENTICATION ERROR HANDLING
Expand Down

0 comments on commit 7a949de

Please sign in to comment.