Merge pull request #290 from wrongecho/extension

Extension updates
This commit is contained in:
Johnny 2022-01-15 22:39:40 -05:00 committed by GitHub
commit 778245ccec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 132 additions and 20 deletions

2
db.sql
View File

@ -1166,6 +1166,8 @@ CREATE TABLE `users` (
`user_token` varchar(200) DEFAULT NULL,
`user_avatar` varchar(200) DEFAULT NULL,
`user_specific_encryption_ciphertext` varchar(200) DEFAULT NULL,
`user_php_session` varchar(255) DEFAULT NULL,
`user_extension_key` varchar(18) DEFAULT NULL,
`user_created_at` datetime NOT NULL,
`user_updated_at` datetime DEFAULT NULL,
`user_archived_at` datetime DEFAULT NULL,

View File

@ -368,10 +368,12 @@ function generateUserSessionKey($site_encryption_master_key){
$_SESSION['user_encryption_session_iv'] = $user_encryption_session_iv;
//Give the user "their" key as a cookie
//By default, this should be HTTPS but we can change to HTTP for development via the config.php file
//By default, this should be HTTPS but we can change to HTTP for development via the config.php file (note that the extension won't work without HTTPS)
include('config.php');
if($config_https_only){
setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/", "", "true", "true");
//setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/", "", "true", "true", ['samesite' => 'None']);
setcookie("user_encryption_session_key", "$user_encryption_session_key", ['path' => '/','secure' => true,'httponly' => true,'samesite' => 'None']);
}
else{
setcookie("user_encryption_session_key", $user_encryption_session_key, 0, "/");

View File

@ -1,5 +1,4 @@
<?php
/*
// Headers to allow extensions access (CORS)
$chrome_id = "chrome-extension://afgpakhonllnmnomchjhidealcpmnegc";
@ -11,29 +10,81 @@ if (isset($_SERVER['HTTP_ORIGIN'])) {
header('Access-Control-Allow-Credentials: true');
}
}
// Additionally, will require cookies set to SameSite None.
include("config.php");
include("functions.php");
session_start();
//SESSION FINGERPRINT
$ip = strip_tags(mysqli_real_escape_string($mysqli,get_ip()));
$os = strip_tags(mysqli_real_escape_string($mysqli,get_os()));
$browser = strip_tags(mysqli_real_escape_string($mysqli,get_web_browser()));
$user_agent = "$os - $browser";
// Check user is logged in
// We do this manually, using check_login will break CORS due to the redirect.
if(!(isset($_SESSION['logged']))){
// Check user is logged in & has extension access
// We're not using the PHP session as we don't want to potentially expose the session cookie with SameSite None
if(!isset($_COOKIE['user_extension_key'])){
$data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not logged into ITFlow.";
$data['message'] = "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie.";
echo(json_encode($data));
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
exit();
}
// User is logged in!
// User has a cookie set with that name, let's verify it.
$user_extension_key = $_COOKIE['user_extension_key'];
// Get user info:
$session_user_id = $_SESSION['user_id'];
// Check the key isn't empty, less than 17 characters or the word "disabled".
if(empty($user_extension_key) OR strlen($user_extension_key) < 16 OR strtolower($user_extension_key) == "disabled"){
$data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie.";
echo(json_encode($data));
$sql = mysqli_query($mysqli,"SELECT * FROM users, user_settings WHERE users.user_id = user_settings.user_id AND users.user_id = $session_user_id");
$row = mysqli_fetch_array($sql);
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
exit();
}
// Cookie seems valid, see if we can associate it with a user ID
$user_extension_key = mysqli_real_escape_string($mysqli, $_COOKIE['user_extension_key']);
$auth_user = mysqli_query($mysqli, "SELECT * FROM users LEFT JOIN user_settings on users.user_id = user_settings.user_id WHERE user_extension_key = '$user_extension_key' LIMIT 1");
$row = mysqli_fetch_array($auth_user);
// Check SQL query state
if(mysqli_num_rows($auth_user) < 1 OR !$auth_user){
$data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not logged into ITFlow, do not have, or did not send the correct extension key cookie.";
echo(json_encode($data));
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
exit();
}
// Sanity check
if(hash('sha256', $row['user_extension_key']) !== hash('sha256', $_COOKIE['user_extension_key'])){
$data['found'] = "FALSE";
$data['message'] = "ITFlow - Validation failed.";
echo(json_encode($data));
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = 'Failed login attempt using extension (get_credential.php)', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW()");
exit();
}
// Success - validated user cookie
// Get the current session from the database so we can decrypt passwords
session_id($row['user_php_session']);
session_start();
$session_user_id = $row['user_id'];
$session_name = $row['user_name'];
$session_email = $row['user_email'];
$session_avatar = $row['user_avatar'];
@ -54,14 +105,21 @@ if($session_user_role == 6){
$session_user_role_display = "Accountant";
}
// Check user access level
// Check user access level is correct
if($session_user_role < 4){
$data['found'] = "FALSE";
$data['message'] = "ITFlow - You are not authorised to use this application.";
echo(json_encode($data));
//Logging
$user_name = mysqli_real_escape_string($mysqli, $session_name);
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'Extension Failed', log_description = '$user_name not authorised to use extension', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_user_id = $session_user_id");
exit();
}
// Lets go!
if(isset($_GET['host'])){
if(!empty($_GET['host'])){
@ -75,6 +133,12 @@ if(isset($_GET['host'])){
$data['username'] = htmlentities($row['login_username']);
$data['password'] = decryptLoginEntry($row['login_password']);
echo json_encode($data);
// Logging
$login_name = mysqli_real_escape_string($mysqli, $row['login_name']);
$login_user = mysqli_real_escape_string($mysqli, $row['login_username']);
mysqli_query($mysqli, "INSERT INTO logs SET log_type = 'Login', log_action = 'Extension requested', log_description = 'Credential $login_name, username $login_user', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), company_id = $session_company_id, log_user_id = $session_user_id");
}
}
}

View File

@ -24,9 +24,10 @@ if($config_https_only){
ini_set("session.cookie_secure", True);
}
session_start();
if(isset($_POST['login'])){
// Sessions should start after the user has POSTed data
session_start();
$email = strip_tags(mysqli_real_escape_string($mysqli,$_POST['email']));
$password = $_POST['password'];
@ -45,13 +46,25 @@ if(isset($_POST['login'])){
$user_name = $row['user_name'];
$user_id = $row['user_id'];
//Setup encryption session key
// Setup encryption session key
if(isset($row['user_specific_encryption_ciphertext'])){
$user_encryption_ciphertext = $row['user_specific_encryption_ciphertext'];
$site_encryption_master_key = decryptUserSpecificKey($user_encryption_ciphertext, $password);
generateUserSessionKey($site_encryption_master_key);
}
// Setup extension
if(isset($row['user_extension_key']) && !empty($row['user_extension_key'])){
// Extension cookie
// Note: Browsers don't accept cookies with SameSite None if they are not HTTPS.
setcookie("user_extension_key", "$row[user_extension_key]", ['path' => '/','secure' => true,'httponly' => true,'samesite' => 'None']);
// Set PHP session in DB so we can access the session encryption data (above)
$user_php_session = session_id();
mysqli_query($mysqli, "UPDATE users SET user_php_session = '$user_php_session' WHERE user_id = '$user_id'");
}
if(empty($token)){
$_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_created_at = NOW(), log_user_id = $user_id");

View File

@ -275,6 +275,23 @@ if(isset($_POST['edit_profile'])){
$logout = TRUE;
}
// Enable extension access, only if it isn't already setup (user doesn't have cookie)
if(isset($_POST['extension']) && $_POST['extension'] == 'Yes'){
if(!isset($_COOKIE['user_extension_key'])){
$extension_key = keygen();
mysqli_query($mysqli, "UPDATE users SET user_extension_key = '$extension_key' WHERE user_id = $user_id");
$extended_log_description .= ", extension access enabled";
$logout = TRUE;
}
}
// Disable extension access
if(!isset($_POST['extension'])){
mysqli_query($mysqli, "UPDATE users SET user_extension_key = '' WHERE user_id = $user_id");
$extended_log_description .= ", extension access disabled";
}
//Logging
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'User Preferences', log_action = 'Modify', log_description = '$session_name modified their preferences$extended_log_description', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_created_at = NOW(), log_user_id = $session_user_id, company_id = $session_company_id");
@ -6640,12 +6657,17 @@ if(isset($_GET['export_client_pdf'])){
if(isset($_GET['logout'])){
mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Logout', log_action = 'Success', log_description = '$session_name logged out', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_created_at = NOW(), log_user_id = $session_user_id");
mysqli_query($mysqli, "UPDATE users SET user_php_session = '' WHERE user_id = '$session_user_id'");
session_start();
setcookie("PHPSESSID", '', time() - 3600, "/");
unset($_COOKIE['PHPSESSID']);
setcookie("user_encryption_session_key", '', time() - 3600, "/");
unset($_COOKIE['user_encryption_session_key']);
setcookie("user_extension_key", '', time() - 3600, "/");
unset($_COOKIE['user_extension_key']);
session_unset();
session_destroy();

View File

@ -30,7 +30,7 @@ $sql_recent_logs = mysqli_query($mysqli,"SELECT * FROM logs
<?php }else{ ?>
<img src="<?php echo "uploads/users/$session_user_id/$session_avatar"; ?>" class="img-circle img-fluid">
<?php } ?>
<h4 class="text-secondary mt-2"><?php echo $session_permission_level_display; ?></h4>
<h4 class="text-secondary mt-2"><?php echo $session_user_role_display; ?></h4>
</center>
<hr>
@ -72,6 +72,15 @@ $sql_recent_logs = mysqli_query($mysqli,"SELECT * FROM logs
<label>Avatar</label>
<input type="file" class="form-control-file" accept="image/*;capture=camera" name="file">
</div>
<div class="form-group">
<div class="form-check">
<input type="checkbox" class="form-check-input" name="extension" id="extension" value="Yes" <?php if(isset($_COOKIE['user_extension_key'])) {echo "checked";} ?>>
<label class="form-check-label" for="extension">Extension access enabled?</label>
<p>Note: You must log out and back in again for these changes take effect.</p>
</div>
</div>
<button type="submit" name="edit_profile" class="btn btn-primary mt-3"><i class="fa fa-fw fa-check"></i> Save</button>