mirror of
https://github.com/itflow-org/itflow
synced 2026-03-21 04:55:39 +00:00
- Add email notification to agents if their 2FA code is entered incorrectly (this may be a sign of account compromise)
- Tidy login code flow so that the "logged" session variable only has to be set in one place, rather than in two (both for 2fa and non-2fa logins)
This commit is contained in:
99
login.php
99
login.php
@@ -12,6 +12,20 @@ include("functions.php");
|
|||||||
$ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip()));
|
$ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip()));
|
||||||
$user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT']));
|
$user_agent = strip_tags(mysqli_real_escape_string($mysqli,$_SERVER['HTTP_USER_AGENT']));
|
||||||
|
|
||||||
|
// Query Settings for "default" company (as companies are being removed shortly)
|
||||||
|
$sql_settings = mysqli_query($mysqli,"SELECT * FROM settings WHERE company_id = 1");
|
||||||
|
$row = mysqli_fetch_array($sql_settings);
|
||||||
|
|
||||||
|
// Mail
|
||||||
|
$config_smtp_host = $row['config_smtp_host'];
|
||||||
|
$config_smtp_port = $row['config_smtp_port'];
|
||||||
|
$config_smtp_encryption = $row['config_smtp_encryption'];
|
||||||
|
$config_smtp_username = $row['config_smtp_username'];
|
||||||
|
$config_smtp_password = $row['config_smtp_password'];
|
||||||
|
$config_mail_from_email = $row['config_mail_from_email'];
|
||||||
|
$config_mail_from_name = $row['config_mail_from_name'];
|
||||||
|
|
||||||
|
|
||||||
// HTTP-Only cookies
|
// HTTP-Only cookies
|
||||||
ini_set("session.cookie_httponly", True);
|
ini_set("session.cookie_httponly", True);
|
||||||
|
|
||||||
@@ -48,23 +62,46 @@ if (isset($_POST['login'])) {
|
|||||||
// Passed login brute force check
|
// Passed login brute force check
|
||||||
$email = strip_tags(mysqli_real_escape_string($mysqli, $_POST['email']));
|
$email = strip_tags(mysqli_real_escape_string($mysqli, $_POST['email']));
|
||||||
$password = $_POST['password'];
|
$password = $_POST['password'];
|
||||||
|
|
||||||
|
$current_code = 0; // Default value
|
||||||
if (isset($_POST['current_code'])) {
|
if (isset($_POST['current_code'])) {
|
||||||
$current_code = strip_tags(mysqli_real_escape_string($mysqli, $_POST['current_code']));
|
$current_code = strip_tags(mysqli_real_escape_string($mysqli, $_POST['current_code']));
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_email = '$email' AND user_archived_at IS NULL AND user_status = 1"));
|
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_email = '$email' AND user_archived_at IS NULL AND user_status = 1"));
|
||||||
|
|
||||||
|
// Check password
|
||||||
if ($row && password_verify($password, $row['user_password'])) {
|
if ($row && password_verify($password, $row['user_password'])) {
|
||||||
|
|
||||||
// User variables
|
// User password correct (partial login)
|
||||||
$token = $row['user_token'];
|
|
||||||
|
// Set temporary user variables
|
||||||
$user_name = strip_tags(mysqli_real_escape_string($mysqli, $row['user_name']));
|
$user_name = strip_tags(mysqli_real_escape_string($mysqli, $row['user_name']));
|
||||||
$user_id = $row['user_id'];
|
$user_id = $row['user_id'];
|
||||||
|
$user_email = $row['user_email'];
|
||||||
|
$token = $row['user_token'];
|
||||||
|
|
||||||
|
// Checking for user 2FA
|
||||||
|
require_once("rfc6238.php");
|
||||||
|
if (empty($token) || TokenAuth6238::verify($token, $current_code)) {
|
||||||
|
|
||||||
|
// FULL LOGIN SUCCESS - 2FA not configured or was successful
|
||||||
|
|
||||||
|
// Determine whether 2FA was used (for logs)
|
||||||
|
$extended_log = ''; // Default value
|
||||||
|
if ($current_code !== 0 ) {
|
||||||
|
$extended_log = 'with 2FA';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logging successful login
|
||||||
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Success', log_description = '$user_name successfully logged in $extended_log', log_ip = '$ip', log_user_agent = '$user_agent', log_user_id = $user_id");
|
||||||
|
|
||||||
// Session info
|
// Session info
|
||||||
$_SESSION['user_id'] = $user_id;
|
$_SESSION['user_id'] = $user_id;
|
||||||
$_SESSION['user_name'] = $user_name;
|
$_SESSION['user_name'] = $user_name;
|
||||||
$_SESSION['user_role'] = $row['user_role'];
|
$_SESSION['user_role'] = $row['user_role'];
|
||||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(78));
|
$_SESSION['csrf_token'] = bin2hex(random_bytes(78));
|
||||||
|
$_SESSION['logged'] = TRUE;
|
||||||
|
|
||||||
// Setup encryption session key
|
// Setup encryption session key
|
||||||
if (isset($row['user_specific_encryption_ciphertext']) && $row['user_role'] > 1) {
|
if (isset($row['user_specific_encryption_ciphertext']) && $row['user_role'] > 1) {
|
||||||
@@ -84,12 +121,6 @@ if (isset($_POST['login'])) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($token)) {
|
|
||||||
// Full Login successful
|
|
||||||
|
|
||||||
$_SESSION['logged'] = TRUE;
|
|
||||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Success', log_description = '$user_name successfully logged in', log_ip = '$ip', log_user_agent = '$user_agent', log_user_id = $user_id");
|
|
||||||
|
|
||||||
// Show start page/dashboard depending on role
|
// Show start page/dashboard depending on role
|
||||||
if ($row['user_role'] == 2) {
|
if ($row['user_role'] == 2) {
|
||||||
header("Location: dashboard_technical.php");
|
header("Location: dashboard_technical.php");
|
||||||
@@ -97,11 +128,15 @@ if (isset($_POST['login'])) {
|
|||||||
header("Location: dashboard_financial.php");
|
header("Location: dashboard_financial.php");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
// Prompt for MFA
|
|
||||||
|
|
||||||
$token_field = "<div class='input-group mb-3'>
|
} else {
|
||||||
<input type='text' class='form-control' placeholder='Token' name='current_code' autofocus>
|
|
||||||
|
// MFA is configured and needs to be confirmed, or was unsuccessful
|
||||||
|
|
||||||
|
// HTML code for the token input field
|
||||||
|
$token_field = "
|
||||||
|
<div class='input-group mb-3'>
|
||||||
|
<input type='text' class='form-control' placeholder='2FA Token' name='current_code' required autofocus>
|
||||||
<div class='input-group-append'>
|
<div class='input-group-append'>
|
||||||
<div class='input-group-text'>
|
<div class='input-group-text'>
|
||||||
<span class='fas fa-key'></span>
|
<span class='fas fa-key'></span>
|
||||||
@@ -109,41 +144,43 @@ if (isset($_POST['login'])) {
|
|||||||
</div>
|
</div>
|
||||||
</div>";
|
</div>";
|
||||||
|
|
||||||
require_once("rfc6238.php");
|
// Log/notify if MFA was unsuccessful
|
||||||
|
if ($current_code !== 0) {
|
||||||
|
|
||||||
if (TokenAuth6238::verify($token, $current_code)) {
|
// Logging
|
||||||
// Full login (with MFA) successful
|
|
||||||
$_SESSION['logged'] = TRUE;
|
|
||||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login 2FA', log_action = 'Success', log_description = '$user_name successfully logged in using 2FA', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_user_id = $user_id");
|
|
||||||
|
|
||||||
// Show start page/dashboard depending on role
|
|
||||||
if ($row['user_role'] == 2) {
|
|
||||||
header("Location: dashboard_technical.php");
|
|
||||||
} else {
|
|
||||||
header("Location: dashboard_financial.php");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = '2FA Failed', log_description = '$user_name failed 2FA', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_user_id = $user_id");
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = '2FA Failed', log_description = '$user_name failed 2FA', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_user_id = $user_id");
|
||||||
|
|
||||||
|
// Email the tech to advise their credentials may be compromised
|
||||||
|
if (!empty($config_smtp_host)) {
|
||||||
|
$subject = "Important: ITFlow failed 2FA login attempt for $user_name";
|
||||||
|
$body = "Hi $user_name, <br><br>A recent login to ITFlow was unsuccessful due to an incorrect 2FA code. If you did not attempt this login, your credentials may be compromised. <br><br>Thanks, <br>ITFlow";
|
||||||
|
|
||||||
|
$mail = sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_password, $config_smtp_encryption, $config_smtp_port,
|
||||||
|
$config_mail_from_email, $config_mail_from_name,
|
||||||
|
$user_email, $user_name,
|
||||||
|
$subject, $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// HTML feedback for incorrect 2FA code
|
||||||
$response = "
|
$response = "
|
||||||
<div class='alert alert-primary'>
|
<div class='alert alert-warning'>
|
||||||
Please Enter 2FA Key!
|
Please Enter 2FA Key!
|
||||||
<button class='close' data-dismiss='alert'>×</button>
|
<button class='close' data-dismiss='alert'>×</button>
|
||||||
</div>
|
</div>";
|
||||||
";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Password incorrect or user doesn't exist - show generic error
|
||||||
|
|
||||||
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Failed', log_description = 'Failed login attempt using $email', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
|
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Failed', log_description = 'Failed login attempt using $email', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
|
||||||
|
|
||||||
$response = "
|
$response = "
|
||||||
<div class='alert alert-danger'>
|
<div class='alert alert-danger'>
|
||||||
Incorrect username or password.
|
Incorrect username or password.
|
||||||
<button class='close' data-dismiss='alert'>×</button>
|
<button class='close' data-dismiss='alert'>×</button>
|
||||||
</div>
|
</div>";
|
||||||
";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user