Skip to content

Commit

Permalink
use symfony cache for managing session-side storage (#954)
Browse files Browse the repository at this point in the history
  • Loading branch information
David Coutadeur committed Aug 28, 2024
1 parent b742d6b commit 0074476
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 83 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"gregwar/captcha": "v1.2.1",
"mxrxdxn/pwned-passwords": "v2.1.0",
"components/jquery": "v3.7.1",
"fortawesome/font-awesome": "6.5.1"
"fortawesome/font-awesome": "6.5.1",
"symfony/cache": "*"
},
"scripts": {
"post-update-cmd": [
Expand Down
11 changes: 11 additions & 0 deletions htdocs/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
require_once("../vendor/autoload.php");
require_once("../lib/functions.inc.php");

use Symfony\Component\Cache\Adapter\FilesystemAdapter;

#==============================================================================
# VARIABLES
#==============================================================================
Expand Down Expand Up @@ -119,6 +121,15 @@
isset($ldap_krb5ccname) ? $ldap_krb5ccname : null
);

#==============================================================================
# Cache Config
#==============================================================================
$sspCache = new FilesystemAdapter(
$namespace = 'sspCache',
$defaultLifetime = 0,
$directory = null
);

#==============================================================================
# Captcha Config
#==============================================================================
Expand Down
19 changes: 7 additions & 12 deletions htdocs/resetbytoken.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,12 @@
$tokenid = $token;
}

# select internal session by $tokenid without relying on cookie or url
# select token in the cache
# will gather login,time and smstoken values from session.
ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);

session_id($tokenid);
session_name("token");
session_start();
$login = $_SESSION['login'];
$smstoken = isset($_SESSION['smstoken']) ? $_SESSION['smstoken'] : false;
$cached_token = $sspCache->getItem($tokenid);
$cached_token_content = $cached_token->get();
$login = $cached_token_content['login'];
$smstoken = isset($cached_token_content['smstoken']) ? $cached_token_content['smstoken'] : false;
$posttoken = isset($_REQUEST['smstoken']) ? $_REQUEST['smstoken'] : 'undefined';

if ( !$login ) {
Expand All @@ -72,7 +68,7 @@
error_log("Token not associated with SMS code ".$posttoken);
} else if (isset($token_lifetime)) {
# Manage lifetime with session content
$tokentime = $_SESSION['time'];
$tokentime = $cached_token_content['time'];
if ( time() - $tokentime > $token_lifetime ) {
$result = "tokennotvalid";
error_log("Token lifetime expired");
Expand Down Expand Up @@ -179,8 +175,7 @@

# Delete token if all is ok
if ( $result === "passwordchanged" ) {
$_SESSION = array();
session_destroy();
$sspCache->deleteItem($tokenid);
}

#==============================================================================
Expand Down
70 changes: 34 additions & 36 deletions htdocs/sendsms.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,13 @@

$tokenid = decrypt($token, $keyphrase);

ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);
# Get session from cache
$cached_token = $sspCache->getItem($tokenid);
$cached_token_content = $cached_token->get();

session_id($tokenid);
session_name("smstoken");
session_start();
$login = $_SESSION['login'];
$sessiontoken = $_SESSION['smstoken'];
$attempts = $_SESSION['attempts'];
$login = $cached_token_content['login'];
$sessiontoken = $cached_token_content['smstoken'];
$attempts = $cached_token_content['attempts'];

if (!$login or !$sessiontoken) {
list($result, $token) = obscure_info_sendsms("tokenattempts",
Expand All @@ -103,27 +101,29 @@
} elseif ($sessiontoken != $smstoken) {
# To have only x tries and not x+1 tries
if ($attempts < ($sms_max_attempts_token - 1)) {
$_SESSION['attempts'] = $attempts + 1;
$cached_token_content['attempts'] = $attempts + 1;
$cached_token->set($cached_token_content);
$sspCache->save($cached_token);
$result = "tokenattempts";
error_log("SMS token $smstoken not valid, attempt $attempts");
} else {
$result = "tokennotvalid";
error_log("SMS token $smstoken not valid");
}
} elseif (isset($token_lifetime)) {
$tokentime = $_SESSION['time'];
$tokentime = $cached_token_content['time'];
if ( time() - $tokentime > $token_lifetime ) {
$result = "tokennotvalid";
error_log("Token lifetime expired");
}
}
if ( $result === "tokennotvalid" ) {
$_SESSION = array();
session_destroy();
# Remove token
$sspCache->deleteItem($tokenid);
}
if ( $result === "" ) {
$_SESSION = array();
session_destroy();
# Remove token
$sspCache->deleteItem($tokenid);
$result = "buildtoken";
}
} elseif (isset($_REQUEST["encrypted_sms_login"])) {
Expand Down Expand Up @@ -203,15 +203,15 @@
# Generate sms token
$smstoken = generate_sms_token($sms_token_length);
# Create temporary session to avoid token replay
ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);

session_name("smstoken");
session_start();
$_SESSION['login'] = $login;
$_SESSION['smstoken'] = $smstoken;
$_SESSION['time'] = time();
$_SESSION['attempts'] = 0;
$smstoken_session_id = hash('sha256', bin2hex(random_bytes(16)));
$smscached_token = $sspCache->getItem($smstoken_session_id);
$smscached_token->set([
'login' => $login,
'smstoken' => $smstoken,
'time' => time(),
'attempts' => 0
]);
$sspCache->save($smscached_token);

$data = array( "sms_attribute" => $sms, "smsresetmessage" => $messages['smsresetmessage'], "smstoken" => $smstoken) ;

Expand All @@ -220,7 +220,7 @@

if ($sms_method === "mail") {
if ($mailer->send_mail($smsmailto, $mail_from, $mail_from_name, $smsmail_subject, $sms_message, $data)) {
$token = encrypt(session_id(), $keyphrase);
$token = encrypt($smstoken_session_id, $keyphrase);
$result = "smssent";
if (!empty($reset_request_log)) {
error_log("Send SMS code $smstoken by $sms_method to $sms\n\n", 3, $reset_request_log);
Expand All @@ -244,7 +244,7 @@
$definedVariables = get_defined_vars(); // get all variables, including configuration
$smsInstance = createSMSInstance($sms_api_lib, $definedVariables);
if ($smsInstance->send_sms_by_api($sms, $sms_message)) {
$token = encrypt(session_id(), $keyphrase);
$token = encrypt($smstoken_session_id, $keyphrase);
$result = "smssent";
if ( !empty($reset_request_log) ) {
error_log("Send SMS code $smstoken by $sms_method to $sms\n\n", 3, $reset_request_log);
Expand All @@ -264,18 +264,16 @@
#==============================================================================
if ($result === "buildtoken") {

# Use PHP session to register token
# We do not generate cookie
ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);

session_name("token");
session_start();
$_SESSION['login'] = $login;
$_SESSION['time'] = time();
$_SESSION['smstoken'] = $smstoken;
$smstoken_session_id = hash('sha256', bin2hex(random_bytes(16)));
$smscached_token = $sspCache->getItem($smstoken_session_id);
$smscached_token->set([
'login' => $login,
'time' => time(),
'smstoken' => $smstoken
]);
$sspCache->save($smscached_token);

$token = encrypt(session_id(), $keyphrase);
$token = encrypt($smstoken_session_id, $keyphrase);

$result = "redirect";
}
Expand Down
53 changes: 19 additions & 34 deletions htdocs/sendtoken.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,11 @@
$result = "emptysendtokenform";

# Generate formtoken
ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);
ini_set("session.use_strict_mode",0);
session_name("formtoken");
session_id(session_create_id());
session_start();
$formtoken = session_id();
$_SESSION['formtoken'] = $formtoken;
error_log("generated token: " . $formtoken);
session_write_close();
$formtoken = hash('sha256', bin2hex(random_bytes(16)));
$cachedToken = $sspCache->getItem($formtoken);
$cachedToken->set($formtoken);
$sspCache->save($cachedToken);
error_log("generated form token: " . $formtoken);
}

# Check the entered username for characters that our installation doesn't support
Expand Down Expand Up @@ -167,22 +162,19 @@
#==============================================================================
if ( !$result ) {

# Use PHP session to register token
# We do not generate cookie
ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);

session_name("token");
session_start();
$_SESSION['login'] = $login;
$_SESSION['time'] = time();

# Use cache to register token
$token_session_id = hash('sha256', bin2hex(random_bytes(16)));
if ( $crypt_tokens ) {
$token = encrypt(session_id(), $keyphrase);
$token = encrypt($token_session_id, $keyphrase);
} else {
$token = session_id();
$token = $token_session_id();
}
session_write_close();
$cached_token = $sspCache->getItem($token_session_id);
$cached_token->set([
'login' => $login,
'time' => time()
]);
$sspCache->save($cached_token);
}


Expand All @@ -192,24 +184,17 @@

if ( !$result ) {
$formtoken = strval($_REQUEST["formtoken"]);
ini_set("session.use_cookies",0);
ini_set("session.use_only_cookies",1);
ini_set("session.use_strict_mode",0);
session_name("formtoken");
session_id($formtoken);
session_start();
if( $_SESSION['formtoken'] == $formtoken )
$cachedToken = $sspCache->getItem($formtoken);
if( $cachedToken->get() == $formtoken )
{
# Remove session
session_unset();
session_destroy();
$sspCache->deleteItem($formtoken);
}
else
{
error_log("Invalid form token: sent: $formtoken, stored: " . $_SESSION['formtoken']);
error_log("Invalid form token: sent: $formtoken, stored: " . $cachedToken->get());
$result = "invalidformtoken";
}
session_write_close();
}

#==============================================================================
Expand Down

0 comments on commit 0074476

Please sign in to comment.