mirror of https://github.com/itflow-org/itflow
Reworked the MFA Enforcement
This commit is contained in:
parent
677bb6b400
commit
52ad2ba322
|
|
@ -54,7 +54,7 @@ $row = mysqli_fetch_array($sql);
|
|||
$session_name = sanitizeInput($row['user_name']);
|
||||
$session_email = $row['user_email'];
|
||||
$session_avatar = $row['user_avatar'];
|
||||
$session_token = $row['user_token'];
|
||||
$session_token = $row['user_token']; // MFA Token
|
||||
$session_user_role = intval($row['user_role']);
|
||||
$session_user_role_display = sanitizeInput($row['user_role_name']);
|
||||
if (isset($row['user_role_is_admin']) && $row['user_role_is_admin'] == 1) {
|
||||
|
|
@ -128,8 +128,3 @@ $session_mobile = isMobile();
|
|||
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT COUNT('notification_id') AS num FROM notifications WHERE (notification_user_id = $session_user_id OR notification_user_id = 0) AND notification_dismissed_at IS NULL"));
|
||||
$num_notifications = $row['num'];
|
||||
|
||||
|
||||
// FORCE MFA Setup
|
||||
//if ($session_user_config_force_mfa == 1 && $session_token == NULL) {
|
||||
// header("Location: force_mfa.php");
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ if (isset($_POST['login'])) {
|
|||
// Validate MFA code
|
||||
if (!empty($current_code) && TokenAuth6238::verify($token, $current_code)) {
|
||||
$mfa_is_complete = true;
|
||||
$extended_log = 'with 2FA';
|
||||
$extended_log = 'with MFA';
|
||||
}
|
||||
|
||||
if ($mfa_is_complete) {
|
||||
|
|
@ -201,8 +201,8 @@ if (isset($_POST['login'])) {
|
|||
|
||||
// Forcing MFA
|
||||
if ($force_mfa == 1 && $token == NULL) {
|
||||
$secretMFA = key32gen();
|
||||
$config_start_page = "post.php?enable_2fa_force&token=$secretMFA&csrf_token=$_SESSION[csrf_token]";
|
||||
//$secretMFA = key32gen();
|
||||
$config_start_page = "mfa_enforcement.php";
|
||||
}
|
||||
|
||||
// Setup encryption session key
|
||||
|
|
|
|||
|
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
require_once "config.php";
|
||||
require_once "functions.php";
|
||||
require_once "check_login.php";
|
||||
require_once 'plugins/totp/totp.php';
|
||||
|
||||
|
||||
// Only generate the token once and store it in session:
|
||||
if (empty($_SESSION['mfa_token'])) {
|
||||
$token = key32gen();
|
||||
$_SESSION['mfa_token'] = $token;
|
||||
}
|
||||
$token = $_SESSION['mfa_token'];
|
||||
|
||||
// Generate QR Code
|
||||
$data = "otpauth://totp/ITFlow:$session_email?secret=$token";
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="robots" content="noindex">
|
||||
|
||||
<title>MFA Enforcement | <?php echo $session_company_name; ?></title>
|
||||
|
||||
<!--
|
||||
Favicon
|
||||
If Fav Icon exists else use the default one
|
||||
-->
|
||||
<?php if(file_exists('uploads/favicon.ico')) { ?>
|
||||
<link rel="icon" type="image/x-icon" href="/uploads/favicon.ico">
|
||||
<?php } ?>
|
||||
|
||||
<!-- Font Awesome Icons -->
|
||||
<link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css">
|
||||
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="plugins/adminlte/css/adminlte.min.css">
|
||||
|
||||
<link href="plugins/toastr/toastr.min.css" rel="stylesheet">
|
||||
<!-- CSS to allow regular button to show as block button in mobile response view using the class btn-responsive -->
|
||||
<style>
|
||||
/*
|
||||
For screens below 576px (xs):
|
||||
- Make the button full-width, display:block
|
||||
*/
|
||||
@media (max-width: 575.98px) {
|
||||
.btn-responsive {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
For screens 576px (sm) and above:
|
||||
- Revert to an inline style
|
||||
*/
|
||||
@media (min-width: 576px) {
|
||||
.btn-responsive {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="plugins/jquery/jquery.min.js"></script>
|
||||
<script src="plugins/toastr/toastr.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body class="hold-transition sidebar-mini layout-fixed layout-navbar-fixed accent-<?php echo nullable_htmlentities($config_theme); ?>">
|
||||
<div class="wrapper text-sm">
|
||||
<div class="container col-md-5">
|
||||
|
||||
<?php require_once 'includes/inc_alert_feedback.php'; ?>
|
||||
|
||||
<div class="card card-dark mt-5">
|
||||
<div class="card-header py-2">
|
||||
<h3 class="card-title mt-2"><i class="fas fa-shield-alt mr-2"></i>Multi-Factor Authentication Enforcement</h3>
|
||||
|
||||
<div class="card-tools">
|
||||
<a href="post.php?logout" class="btn btn-light btn-sm text-dark">
|
||||
<i class="fa fa-door-open mr-2"></i>Logout
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="post.php" method="post" autocomplete="off">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token'] ?>">
|
||||
|
||||
<div class="text-center">
|
||||
<h4>Scan this code into your app</h4>
|
||||
<img src='plugins/barcode/barcode.php?f=png&s=qr&d=<?php echo $data; ?>'>
|
||||
<div>Can't Scan? <span class="text-secondary">Copy and paste the secret below</span>
|
||||
</div>
|
||||
<hr>
|
||||
<p><span class='text-secondary'>Secret:</span> <?php echo $token; ?>
|
||||
<button type="button" class='btn btn-sm clipboardjs' data-clipboard-text='<?php echo $token; ?>'><i class='far fa-copy text-secondary'></i></button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span>
|
||||
</div>
|
||||
<input type="text" class="form-control" inputmode="numeric" pattern="[0-9]*" minlength="6" maxlength="6" name="verify_code" placeholder="Enter 6 digit code to verify MFA" required>
|
||||
<div class="input-group-append">
|
||||
<button type="submit" name="enable_mfa" class="btn btn-primary text-bold"><i class="fa fa-check mr-2"></i>Enable</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- ./wrapper -->
|
||||
|
||||
|
||||
<!-- REQUIRED SCRIPTS -->
|
||||
|
||||
<!-- Bootstrap 4 -->
|
||||
<script src="plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Custom js-->
|
||||
<script src="plugins/clipboardjs/clipboard.min.js"></script>
|
||||
|
||||
|
||||
|
||||
<!-- AdminLTE App -->
|
||||
<script src="plugins/adminlte/js/adminlte.min.js"></script>
|
||||
<script>
|
||||
|
||||
//Prevents resubmit on forms
|
||||
if(window.history.replaceState){
|
||||
window.history.replaceState(null, null, window.location.href);
|
||||
}
|
||||
|
||||
// Slide alert up after 4 secs
|
||||
$("#alert").fadeTo(5000, 500).slideUp(500, function(){
|
||||
$("#alert").slideUp(500);
|
||||
});
|
||||
|
||||
// ClipboardJS
|
||||
|
||||
//Fix to allow Clipboard Copying within Bootstrap Modals
|
||||
//For use in Bootstrap Modals or with any other library that changes the focus you'll want to set the focused element as the container value.
|
||||
$.fn.modal.Constructor.prototype._enforceFocus = function() {};
|
||||
|
||||
// Tooltip
|
||||
|
||||
$('button').tooltip({
|
||||
trigger: 'click',
|
||||
placement: 'bottom'
|
||||
});
|
||||
|
||||
function setTooltip(btn, message) {
|
||||
$(btn).tooltip('hide')
|
||||
.attr('data-original-title', message)
|
||||
.tooltip('show');
|
||||
}
|
||||
|
||||
function hideTooltip(btn) {
|
||||
setTimeout(function() {
|
||||
$(btn).tooltip('hide');
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// Clipboard
|
||||
|
||||
var clipboard = new ClipboardJS('.clipboardjs');
|
||||
|
||||
clipboard.on('success', function(e) {
|
||||
setTooltip(e.trigger, 'Copied!');
|
||||
hideTooltip(e.trigger);
|
||||
});
|
||||
|
||||
clipboard.on('error', function(e) {
|
||||
setTooltip(e.trigger, 'Failed!');
|
||||
hideTooltip(e.trigger);
|
||||
});
|
||||
|
||||
// Enable Popovers
|
||||
$(function () {
|
||||
$('[data-toggle="popover"]').popover()
|
||||
});
|
||||
</script>
|
||||
<script src="js/confirm_modal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -190,24 +190,6 @@ if (isset($_POST['edit_your_user_preferences'])) {
|
|||
header("Location: " . $_SERVER["HTTP_REFERER"]);
|
||||
}
|
||||
|
||||
|
||||
if (isset($_POST['verify'])) {
|
||||
|
||||
require_once "plugins/totp/totp.php";
|
||||
|
||||
$currentcode = intval($_POST['code']); //code to validate, for example received from device
|
||||
|
||||
if (TokenAuth6238::verify($session_token, $currentcode)) {
|
||||
$_SESSION['alert_message'] = "VALID!";
|
||||
}else{
|
||||
$_SESSION['alert_type'] = "error";
|
||||
$_SESSION['alert_message'] = "IN-VALID!";
|
||||
}
|
||||
|
||||
header("Location: " . $_SERVER["HTTP_REFERER"]);
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['enable_mfa'])) {
|
||||
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
|
@ -230,7 +212,7 @@ if (isset($_POST['enable_mfa'])) {
|
|||
// SUCCESS
|
||||
mysqli_query($mysqli,"UPDATE users SET user_token = '$token' WHERE user_id = $session_user_id");
|
||||
|
||||
// Delete any existing 2FA tokens - these browsers should be re-validated
|
||||
// Delete any existing MFA tokens - these browsers should be re-validated
|
||||
mysqli_query($mysqli, "DELETE FROM remember_tokens WHERE remember_token_user_id = $session_user_id");
|
||||
|
||||
// Logging
|
||||
|
|
@ -241,6 +223,16 @@ if (isset($_POST['enable_mfa'])) {
|
|||
// Clear the mfa_token from the session to avoid re-use.
|
||||
unset($_SESSION['mfa_token']);
|
||||
|
||||
// Check if the previous page is mfa_enforcement.php
|
||||
if (isset($_SERVER['HTTP_REFERER'])) {
|
||||
$previousPage = basename(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH));
|
||||
if ($previousPage === 'mfa_enforcement.php') {
|
||||
// Redirect back to mfa_enforcement.php
|
||||
header("Location: $config_start_page");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// FAILURE
|
||||
$_SESSION['alert_type'] = "error";
|
||||
|
|
@ -248,7 +240,19 @@ if (isset($_POST['enable_mfa'])) {
|
|||
|
||||
// Set a flag to automatically open the MFA modal again
|
||||
$_SESSION['show_mfa_modal'] = true;
|
||||
}
|
||||
|
||||
// Check if the previous page is mfa_enforcement.php
|
||||
if (isset($_SERVER['HTTP_REFERER'])) {
|
||||
$previousPage = basename(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH));
|
||||
if ($previousPage === 'mfa_enforcement.php') {
|
||||
// Redirect back to mfa_enforcement.php
|
||||
header("Location: " . $_SERVER['HTTP_REFERER']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
header("Location: user_security.php");
|
||||
exit;
|
||||
|
|
@ -262,6 +266,9 @@ if (isset($_GET['disable_mfa'])){
|
|||
|
||||
mysqli_query($mysqli,"UPDATE users SET user_token = '' WHERE user_id = $session_user_id");
|
||||
|
||||
// Delete any existing MFA tokens - these browsers should be re-validated
|
||||
mysqli_query($mysqli, "DELETE FROM remember_tokens WHERE remember_token_user_id = $session_user_id");
|
||||
|
||||
// Sanitize Config Vars from get_settings.php and Session Vars from check_login.php
|
||||
$config_mail_from_name = sanitizeInput($config_mail_from_name);
|
||||
$config_mail_from_email = sanitizeInput($config_mail_from_email);
|
||||
|
|
@ -295,78 +302,6 @@ if (isset($_GET['disable_mfa'])){
|
|||
|
||||
}
|
||||
|
||||
if (isset($_POST['enable_2fa']) || isset($_GET['enable_2fa_force'])) {
|
||||
|
||||
// CSRF Check
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
$extended_log_description = "";
|
||||
$token = sanitizeInput($_POST['token']);
|
||||
} else {
|
||||
// If this is a GET request then we forced MFA as part of login
|
||||
validateCSRFToken($_GET['csrf_token']);
|
||||
|
||||
$extended_log_description = "(forced)";
|
||||
$token = sanitizeInput($_GET['token']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
mysqli_query($mysqli,"UPDATE users SET user_token = '$token' WHERE user_id = $session_user_id");
|
||||
|
||||
// Delete any existing 2FA tokens - these browsers should be re-validated
|
||||
mysqli_query($mysqli, "DELETE FROM remember_tokens WHERE remember_token_user_id = $session_user_id");
|
||||
|
||||
// Logging
|
||||
logAction("User Account", "Edit", "$session_name enabled MFA on their account $extended_log_description");
|
||||
|
||||
$_SESSION['alert_message'] = "Two-factor authentication enabled $extended_log_description";
|
||||
|
||||
header("Location: user_security.php");
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['disable_2fa'])){
|
||||
|
||||
// CSRF Check
|
||||
validateCSRFToken($_POST['csrf_token']);
|
||||
|
||||
mysqli_query($mysqli,"UPDATE users SET user_token = '' WHERE user_id = $session_user_id");
|
||||
|
||||
// Sanitize Config Vars from get_settings.php and Session Vars from check_login.php
|
||||
$config_mail_from_name = sanitizeInput($config_mail_from_name);
|
||||
$config_mail_from_email = sanitizeInput($config_mail_from_email);
|
||||
$config_app_name = sanitizeInput($config_app_name);
|
||||
|
||||
// Email notification
|
||||
if (!empty($config_smtp_host)) {
|
||||
$subject = "$config_app_name account update confirmation for $session_name";
|
||||
$body = "Hi $session_name, <br><br>Your $config_app_name account has been updated, details below: <br><br> <b>2FA was disabled.</b> <br><br> If you did not perform this change, contact your $config_app_name administrator immediately. <br><br>Thanks, <br>ITFlow<br>$session_company_name";
|
||||
|
||||
$data = [
|
||||
[
|
||||
'from' => $config_mail_from_email,
|
||||
'from_name' => $config_mail_from_name,
|
||||
'recipient' => $session_email,
|
||||
'recipient_name' => $session_name,
|
||||
'subject' => $subject,
|
||||
'body' => $body
|
||||
]
|
||||
];
|
||||
$mail = addToMailQueue($data);
|
||||
}
|
||||
|
||||
// Logging
|
||||
logAction("User Account", "Edit", "$session_name disabled MFA on their account");
|
||||
|
||||
$_SESSION['alert_type'] = "error";
|
||||
$_SESSION['alert_message'] = "Two-factor authentication disabled";
|
||||
|
||||
header("Location: " . $_SERVER["HTTP_REFERER"]);
|
||||
|
||||
}
|
||||
|
||||
if (isset($_POST['revoke_your_2fa_remember_tokens'])) {
|
||||
|
||||
// CSRF
|
||||
|
|
|
|||
Loading…
Reference in New Issue