Skip to content

Commit

Permalink
3.1.1
Browse files Browse the repository at this point in the history
Fix for Vulnerability: Bypassing 2FA Authentication (Hamidreza Faghani)
  • Loading branch information
root authored and root committed Dec 13, 2023
1 parent 3a8c506 commit bee3f61
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 20 deletions.
2 changes: 1 addition & 1 deletion includes/config/include.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
define('TP_VERSION', '3.1.1');
define("UPGRADE_MIN_DATE", "1702452416");
define('TP_VERSION_MINOR', '6');
define('TP_VERSION_MINOR', '7');
define('TP_TOOL_NAME', 'Teampass');
define('TP_ONE_DAY_SECONDS', 86400);
define('TP_ONE_WEEK_SECONDS', 604800);
Expand Down
7 changes: 4 additions & 3 deletions includes/core/login.js.php
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,8 @@ function getGASynchronization() {
data = {
'login': $("#login").val(),
'pw': $("#pw").val(),
'send_mail': 1
'send_mail': 1,
'token': CreateRandomString(100)
}
$.post(
'sources/main.queries.php', {
Expand Down Expand Up @@ -874,9 +875,9 @@ function send_user_new_temporary_ga_code() {
data = {
'login': $("#login").val(),
'pwd': $("#pw").val(),
'send_email': 1
'send_email': 1,
'token': CreateRandomString(100)
}
//console.log(data);
$.post(
'sources/main.queries.php', {
type: 'ga_generate_qr',
Expand Down
2 changes: 1 addition & 1 deletion install/install.queries.php
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ function encryptFollowingDefuse($message, $ascii_key)
`token` varchar(255) NOT NULL,
`reason` varchar(255) NOT NULL,
`creation_timestamp` varchar(50) NOT NULL,
`end_timestamp` varchar(50) NOT NULL,
`end_timestamp` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) CHARSET=utf8;'
);
Expand Down
6 changes: 6 additions & 0 deletions install/upgrade_run_3.1.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@
) CHARSET=utf8;'
);

// Alter table TOKENS
mysqli_query(
$db_link,
'ALTER TABLE `' . $pre . 'tokens` CHANGE `end_timestamp` `end_timestamp` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL;'
);

//---<END 3.1.1

//---------------------------------------------------------------------
Expand Down
74 changes: 59 additions & 15 deletions sources/main.queries.php
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ function userHandler(string $post_type, /*php8 array|null|string*/ $dataReceived
(string) filter_var($dataReceived['send_email'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
(string) filter_var($dataReceived['login'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
(string) filter_var($dataReceived['pwd'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
(string) filter_var($dataReceived['token'], FILTER_SANITIZE_FULL_SPECIAL_CHARS),
$SETTINGS
);

Expand Down Expand Up @@ -996,12 +997,13 @@ function generateQRCode(
$post_send_mail,
$post_login,
$post_pwd,
$post_token,
array $SETTINGS
): string
{
// Load user's language
$lang = new Language();
$lang = new Language();

// is this allowed by setting
if (isKeyExistingAndEqual('ga_reset_by_user', 0, $SETTINGS) === true
&& (null === $post_demand_origin || $post_demand_origin !== 'users_management_list')
Expand All @@ -1019,20 +1021,20 @@ function generateQRCode(
// Check if user exists
if (isValueSetNullEmpty($post_id) === true) {
// Get data about user
$data = DB::queryfirstrow(
$dataUser = DB::queryfirstrow(
'SELECT id, email, pw
FROM ' . prefixTable('users') . '
WHERE login = %s',
$post_login
);
} else {
$data = DB::queryfirstrow(
$dataUser = DB::queryfirstrow(
'SELECT id, login, email, pw
FROM ' . prefixTable('users') . '
WHERE id = %i',
$post_id
);
$post_login = $data['login'];
$post_login = $dataUser['login'];
}
// Get number of returned users
$counter = DB::count();
Expand All @@ -1054,8 +1056,8 @@ function generateQRCode(
// load passwordLib library
$pwdlib = new PasswordLib();
if (
isSetArrayOfValues([$post_pwd, $data['pw']]) === true
&& $pwdlib->verifyPasswordHash($post_pwd, $data['pw']) === false
isSetArrayOfValues([$post_pwd, $dataUser['pw']]) === true
&& $pwdlib->verifyPasswordHash($post_pwd, $dataUser['pw']) === false
&& $post_demand_origin !== 'users_management_list'
) {
// checked the given password
Expand All @@ -1070,7 +1072,7 @@ function generateQRCode(
);
}

if (empty($data['email']) === true) {
if (empty($dataUser['email']) === true) {
return prepareExchangedData(
array(
'error' => true,
Expand All @@ -1079,6 +1081,38 @@ function generateQRCode(
'encode'
);
}

// Check if token already used
$dataToken = DB::queryfirstrow(
'SELECT end_timestamp, reason
FROM ' . prefixTable('tokens') . '
WHERE token = %s AND user_id = %i',
$post_token,
$dataUser['id']
);
$tokenId = '';
if (DB::count() > 0 && is_null($dataToken['end_timestamp']) === false && $dataToken['reason'] === 'auth_qr_code') {
// This token has already been used
return prepareExchangedData(
array(
'error' => true,
'message' => 'TOKEN already used',//$lang->get('no_email_set'),
),
'encode'
);
} elseif(DB::count() === 0) {
// Store token for this action
DB::insert(
prefixTable('tokens'),
array(
'user_id' => (int) $dataUser['id'],
'token' => $post_token,
'reason' => 'auth_qr_code',
'creation_timestamp' => time(),
)
);
$tokenId = DB::insertId();
}

// generate new GA user code
$tfa = new TwoFactorAuth($SETTINGS['ga_website_name']);
Expand All @@ -1092,11 +1126,21 @@ function generateQRCode(
'ga_temporary_code' => $gaTemporaryCode,
],
'id = %i',
$data['id']
$dataUser['id']
);

// Log event
logEvents($SETTINGS, 'user_connection', 'at_2fa_google_code_send_by_email', (string) $data['id'], stripslashes($post_login), stripslashes($post_login));
logEvents($SETTINGS, 'user_connection', 'at_2fa_google_code_send_by_email', (string) $dataUser['id'], stripslashes($post_login), stripslashes($post_login));

// Update token status
DB::update(
prefixTable('tokens'),
[
'end_timestamp' => time(),
],
'id = %i',
$tokenId
);

// send mail?
if ((int) $post_send_mail === 1) {
Expand All @@ -1107,7 +1151,7 @@ function generateQRCode(
$gaTemporaryCode,
$lang->get('email_ga_text')
),
$data['email'],
$dataUser['email'],
$SETTINGS
);

Expand All @@ -1116,10 +1160,10 @@ function generateQRCode(
array(
'error' => false,
'message' => $post_send_mail,
'email' => $data['email'],
'email' => $dataUser['email'],
'email_result' => str_replace(
'#email#',
'<b>' . obfuscateEmail($data['email']) . '</b>',
'<b>' . obfuscateEmail($dataUser['email']) . '</b>',
addslashes($lang->get('admin_email_result_ok'))
),
),
Expand All @@ -1132,10 +1176,10 @@ function generateQRCode(
array(
'error' => false,
'message' => '',
'email' => $data['email'],
'email' => $dataUser['email'],
'email_result' => str_replace(
'#email#',
'<b>' . obfuscateEmail($data['email']) . '</b>',
'<b>' . obfuscateEmail($dataUser['email']) . '</b>',
addslashes($lang->get('admin_email_result_ok'))
),
),
Expand Down

1 comment on commit bee3f61

@nemesis1695
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good time
Please register this vulnerability globally so that the cve of this vulnerability and security event are recorded.

Please sign in to comment.