mirror of
https://github.com/itflow-org/itflow
synced 2026-03-25 23:05:37 +00:00
@@ -20,7 +20,7 @@ ITFlow is in Beta.
|
|||||||
|
|
||||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||||
|
|
||||||
If you have discovered a security issue, please report it to us in as much detail as possible so we can fix it.
|
If you have discovered a security issue, please report it to us in as much detail as possible, so we can fix it.
|
||||||
You should expect to receive an initial acknowledgement within 72 hours. If you do not, please get in touch discretely via GitHub issues/Forum/Discord to ensure we received your e-mail.
|
You should expect to receive an initial acknowledgement within 72 hours. If you do not, please get in touch discretely via GitHub issues/Forum/Discord to ensure we received your e-mail.
|
||||||
|
|
||||||
Security contact:
|
Security contact:
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ if(!isset($config_enable_setup) || $config_enable_setup == 1){
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check user is logged in with a valid session
|
||||||
if (!isset($_SESSION['logged']) || !$_SESSION['logged']) {
|
if (!isset($_SESSION['logged']) || !$_SESSION['logged']) {
|
||||||
header("Location: login.php");
|
header("Location: login.php");
|
||||||
die;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SESSION FINGERPRINT
|
// SESSION FINGERPRINT
|
||||||
@@ -71,7 +72,7 @@ $session_company_currency = $row['company_currency'];
|
|||||||
|
|
||||||
include("get_settings.php");
|
include("get_settings.php");
|
||||||
|
|
||||||
//Detects if using an apple device and uses apple maps instead of google
|
//Detects if using an Apple device and uses Apple Maps instead of google
|
||||||
$iPod = stripos($_SERVER['HTTP_USER_AGENT'],"iPod");
|
$iPod = stripos($_SERVER['HTTP_USER_AGENT'],"iPod");
|
||||||
$iPhone = stripos($_SERVER['HTTP_USER_AGENT'],"iPhone");
|
$iPhone = stripos($_SERVER['HTTP_USER_AGENT'],"iPhone");
|
||||||
$iPad = stripos($_SERVER['HTTP_USER_AGENT'],"iPad");
|
$iPad = stripos($_SERVER['HTTP_USER_AGENT'],"iPad");
|
||||||
@@ -89,4 +90,4 @@ $num_notifications = $row['num'];
|
|||||||
//Set Currency Format
|
//Set Currency Format
|
||||||
$currency_format = numfmt_create($session_company_locale, NumberFormatter::CURRENCY);
|
$currency_format = numfmt_create($session_company_locale, NumberFormatter::CURRENCY);
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<div class="mb-4" style="text-align: center;">
|
<div class="mb-4" style="text-align: center;">
|
||||||
<i class="far fa-10x fa-times-circle text-danger mb-3 mt-3"></i>
|
<i class="far fa-10x fa-times-circle text-danger mb-3 mt-3"></i>
|
||||||
<h2>Are you sure?</h2>
|
<h2>Are you sure?</h2>
|
||||||
<h6 class="mb-4 text-secondary">Do you really want to <b>delete <?php echo $client_name; ?></b> and all associated data including financial data, logs, shared links etc? This process cannot be undone.</h6>
|
<h6 class="mb-4 text-secondary">Do you really want to <b>delete <?php echo $client_name; ?></b> and all associated data including financial data, logs, shared links etc.? This process cannot be undone.</h6>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="hidden" id="clientName<?php echo $client_id ?>" value="<?php echo $client_name; ?>">
|
<input type="hidden" id="clientName<?php echo $client_id ?>" value="<?php echo $client_name; ?>">
|
||||||
<input class="form-control" type="text" id="clientNameProvided<?php echo $client_id ?>" onkeyup="validateClientNameDelete(<?php echo $client_id ?>)" placeholder="Please enter: '<?php echo $client_name; ?>'">
|
<input class="form-control" type="text" id="clientNameProvided<?php echo $client_id ?>" onkeyup="validateClientNameDelete(<?php echo $client_id ?>)" placeholder="Please enter: '<?php echo $client_name; ?>'">
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli,"SELECT FOUND_ROWS()"));
|
|||||||
<div class="card-tools">
|
<div class="card-tools">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTicketModal"><i class="fas fa-fw fa-plus"></i> New Ticket</button>
|
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addTicketModal"><i class="fas fa-fw fa-plus"></i> New Ticket</button>
|
||||||
</button>
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
<button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown"></button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addScheduledTicketModal">Scheduled</a>
|
<a class="dropdown-item text-dark" href="#" data-toggle="modal" data-target="#addScheduledTicketModal">Scheduled</a>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ $largest_income_month = 0;
|
|||||||
$sql_total_payments_to_invoices = mysqli_query($mysqli,"SELECT SUM(payment_amount) AS total_payments_to_invoices FROM payments WHERE YEAR(payment_date) = $year AND company_id = $session_company_id");
|
$sql_total_payments_to_invoices = mysqli_query($mysqli,"SELECT SUM(payment_amount) AS total_payments_to_invoices FROM payments WHERE YEAR(payment_date) = $year AND company_id = $session_company_id");
|
||||||
$row = mysqli_fetch_array($sql_total_payments_to_invoices);
|
$row = mysqli_fetch_array($sql_total_payments_to_invoices);
|
||||||
$total_payments_to_invoices = $row['total_payments_to_invoices'];
|
$total_payments_to_invoices = $row['total_payments_to_invoices'];
|
||||||
//Do not grab transfer payment as these have an category_id of 0
|
//Do not grab transfer payment as these have a category_id of 0
|
||||||
$sql_total_revenues = mysqli_query($mysqli,"SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE YEAR(revenue_date) = $year AND revenue_category_id > 0 AND company_id = $session_company_id");
|
$sql_total_revenues = mysqli_query($mysqli,"SELECT SUM(revenue_amount) AS total_revenues FROM revenues WHERE YEAR(revenue_date) = $year AND revenue_category_id > 0 AND company_id = $session_company_id");
|
||||||
$row = mysqli_fetch_array($sql_total_revenues);
|
$row = mysqli_fetch_array($sql_total_revenues);
|
||||||
$total_revenues = $row['total_revenues'];
|
$total_revenues = $row['total_revenues'];
|
||||||
|
|||||||
@@ -134,7 +134,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-file-alt"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-file-alt"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" name="reference" placeholder="Enter a reference" value="<?php $expense_reference; ?>">
|
<input type="text" class="form-control" name="reference" placeholder="Enter a reference" value="<?php echo $expense_reference; ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ function get_device(){
|
|||||||
}
|
}
|
||||||
if (strpos(strtolower(get_user_agent()),'opera mini') > 0) {
|
if (strpos(strtolower(get_user_agent()),'opera mini') > 0) {
|
||||||
$mobile_browser++;
|
$mobile_browser++;
|
||||||
//Check for tablets on opera mini alternative headers
|
//Check for tablets on Opera Mini alternative headers
|
||||||
$stock_ua = strtolower(isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA'])?$_SERVER['HTTP_X_OPERAMINI_PHONE_UA']:(isset($_SERVER['HTTP_DEVICE_STOCK_UA'])?$_SERVER['HTTP_DEVICE_STOCK_UA']:''));
|
$stock_ua = strtolower(isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA'])?$_SERVER['HTTP_X_OPERAMINI_PHONE_UA']:(isset($_SERVER['HTTP_DEVICE_STOCK_UA'])?$_SERVER['HTTP_DEVICE_STOCK_UA']:''));
|
||||||
if (preg_match('/(tablet|ipad|playbook)|(android(?!.*mobile))/i', $stock_ua)) {
|
if (preg_match('/(tablet|ipad|playbook)|(android(?!.*mobile))/i', $stock_ua)) {
|
||||||
$tablet_browser++;
|
$tablet_browser++;
|
||||||
@@ -186,8 +186,7 @@ function truncate($text, $chars) {
|
|||||||
$text = $text." ";
|
$text = $text." ";
|
||||||
$text = substr($text,0,$chars);
|
$text = substr($text,0,$chars);
|
||||||
$text = substr($text,0,strrpos($text,' '));
|
$text = substr($text,0,strrpos($text,' '));
|
||||||
$text = $text."...";
|
return $text."...";
|
||||||
return $text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPhoneNumber($phoneNumber) {
|
function formatPhoneNumber($phoneNumber) {
|
||||||
@@ -236,9 +235,7 @@ function setupFirstUserSpecificKey($user_password, $site_encryption_master_key){
|
|||||||
//Encrypt the master key with the users kdf'd hash and the IV
|
//Encrypt the master key with the users kdf'd hash and the IV
|
||||||
$ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
$ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
||||||
|
|
||||||
$user_encryption_ciphertext = $salt . $iv . $ciphertext;
|
return $salt . $iv . $ciphertext;
|
||||||
|
|
||||||
return $user_encryption_ciphertext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -264,9 +261,7 @@ function encryptUserSpecificKey($user_password){
|
|||||||
// Encrypt the master key with the users kdf'd hash and the IV
|
// Encrypt the master key with the users kdf'd hash and the IV
|
||||||
$ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
$ciphertext = openssl_encrypt($site_encryption_master_key, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
||||||
|
|
||||||
$user_encryption_ciphertext = $salt . $iv . $ciphertext;
|
return $salt . $iv . $ciphertext;
|
||||||
|
|
||||||
return $user_encryption_ciphertext;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,14 +277,13 @@ function decryptUserSpecificKey($user_encryption_ciphertext, $user_password){
|
|||||||
$user_password_kdhash = hash_pbkdf2('sha256', $user_password, $salt, 100000, 16);
|
$user_password_kdhash = hash_pbkdf2('sha256', $user_password, $salt, 100000, 16);
|
||||||
|
|
||||||
//Use this hash to get the original/master key
|
//Use this hash to get the original/master key
|
||||||
$site_encryption_master_key = openssl_decrypt($ciphertext, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
return openssl_decrypt($ciphertext, 'aes-128-cbc', $user_password_kdhash, 0, $iv);
|
||||||
return $site_encryption_master_key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generates what is probably best described as a session key (ephemeral-ish)
|
Generates what is probably best described as a session key (ephemeral-ish)
|
||||||
- Allows us to store the master key on the server whilst the user is using the application, without prompting to type their password everytime they want to decrypt a credential
|
- Allows us to store the master key on the server whilst the user is using the application, without prompting to type their password everytime they want to decrypt a credential
|
||||||
- Ciphertext/IV is stored on the server in the users session, encryption key is controlled/provided by the user as a cookie
|
- Ciphertext/IV is stored on the server in the users' session, encryption key is controlled/provided by the user as a cookie
|
||||||
- Only the user can decrypt their session ciphertext to get the master key
|
- Only the user can decrypt their session ciphertext to get the master key
|
||||||
- Encryption key never hits the disk in cleartext
|
- Encryption key never hits the disk in cleartext
|
||||||
*/
|
*/
|
||||||
@@ -330,8 +324,7 @@ function decryptLoginEntry($login_password_ciphertext){
|
|||||||
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
|
$site_encryption_master_key = openssl_decrypt($user_encryption_session_ciphertext, 'aes-128-cbc', $user_encryption_session_key, 0, $user_encryption_session_iv);
|
||||||
|
|
||||||
// Decrypt the login password using the master key
|
// Decrypt the login password using the master key
|
||||||
$login_password_cleartext = openssl_decrypt($login_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $login_iv);
|
return openssl_decrypt($login_ciphertext, 'aes-128-cbc', $site_encryption_master_key, 0, $login_iv);
|
||||||
return $login_password_cleartext;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,8 +343,7 @@ function encryptLoginEntry($login_password_cleartext){
|
|||||||
//Encrypt the website/asset login using the master key
|
//Encrypt the website/asset login using the master key
|
||||||
$ciphertext = openssl_encrypt($login_password_cleartext, 'aes-128-cbc', $site_encryption_master_key, 0, $iv);
|
$ciphertext = openssl_encrypt($login_password_cleartext, 'aes-128-cbc', $site_encryption_master_key, 0, $iv);
|
||||||
|
|
||||||
$login_password_ciphertext = $iv . $ciphertext;
|
return $iv . $ciphertext;
|
||||||
return $login_password_ciphertext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get domain expiration date
|
// Get domain expiration date
|
||||||
@@ -450,9 +442,7 @@ function strto_AZaz09($string){
|
|||||||
//$string = str_replace(' ', '_', $string);
|
//$string = str_replace(' ', '_', $string);
|
||||||
|
|
||||||
// Gets rid of non-alphanumerics
|
// Gets rid of non-alphanumerics
|
||||||
$strto_AZaz09 = preg_replace( '/[^A-Za-z0-9_]/', '', $string );
|
return preg_replace('/[^A-Za-z0-9_]/', '', $string);
|
||||||
|
|
||||||
return $strto_AZaz09;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cross-Site Request Forgery check for sensitive functions
|
// Cross-Site Request Forgery check for sensitive functions
|
||||||
@@ -524,7 +514,6 @@ function sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_
|
|||||||
$mail->addAddress("$to_email", "$to_name"); // Add a recipient
|
$mail->addAddress("$to_email", "$to_name"); // Add a recipient
|
||||||
|
|
||||||
// Content
|
// Content
|
||||||
$mail->isHTML(true); // Set email format to HTML
|
|
||||||
$mail->Subject = "$subject"; // Subject
|
$mail->Subject = "$subject"; // Subject
|
||||||
$mail->Body = "$body"; // Content
|
$mail->Body = "$body"; // Content
|
||||||
|
|
||||||
@@ -540,9 +529,9 @@ function sendSingleEmail($config_smtp_host, $config_smtp_username, $config_smtp_
|
|||||||
}
|
}
|
||||||
|
|
||||||
catch(Exception $e) {
|
catch(Exception $e) {
|
||||||
// If we couldn't send the message return the error so we can log it
|
// If we couldn't send the message return the error, so we can log it
|
||||||
return "Message not sent. Mailer Error: {$mail->ErrorInfo}";
|
return "Message not sent. Mailer Error: {$mail->ErrorInfo}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -927,4 +927,3 @@ $asset_status_array = array(
|
|||||||
'Retired'
|
'Retired'
|
||||||
);
|
);
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -52,4 +52,3 @@ if(isset($_GET['decline_quote'], $_GET['company_id'], $_GET['url_key'])){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -10,4 +10,3 @@ include("inc_wrapper.php");
|
|||||||
include("inc_alert_feedback.php");
|
include("inc_alert_feedback.php");
|
||||||
include("pagination_head.php");
|
include("pagination_head.php");
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -9,4 +9,3 @@ include("reports_side_nav.php");
|
|||||||
include("inc_wrapper.php");
|
include("inc_wrapper.php");
|
||||||
include("inc_alert_feedback.php");
|
include("inc_alert_feedback.php");
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -13,4 +13,3 @@ include("inc_wrapper.php");
|
|||||||
include("inc_alert_feedback.php");
|
include("inc_alert_feedback.php");
|
||||||
include("pagination_head.php");
|
include("pagination_head.php");
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -128,7 +128,7 @@ if (isset($_POST['login'])) {
|
|||||||
// Note: Browsers don't accept cookies with SameSite None if they are not HTTPS.
|
// 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']);
|
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)
|
// Set PHP session in DB, so we can access the session encryption data (above)
|
||||||
$user_php_session = session_id();
|
$user_php_session = session_id();
|
||||||
mysqli_query($mysqli, "UPDATE users SET user_php_session = '$user_php_session' WHERE user_id = '$user_id'");
|
mysqli_query($mysqli, "UPDATE users SET user_php_session = '$user_php_session' WHERE user_id = '$user_id'");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ $auth_code_url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/au
|
|||||||
$token_grant_url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
|
$token_grant_url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
|
||||||
|
|
||||||
// Initial Login Request, via Microsoft
|
// Initial Login Request, via Microsoft
|
||||||
// Returns a authorization code if login was successful
|
// Returns an authorization code if login was successful
|
||||||
if ($_SERVER['REQUEST_METHOD'] == "GET") {
|
if ($_SERVER['REQUEST_METHOD'] == "GET") {
|
||||||
|
|
||||||
$params = array (
|
$params = array (
|
||||||
@@ -45,7 +45,7 @@ if ($_SERVER['REQUEST_METHOD'] == "GET") {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login was successful, Microsoft has returned us a authorization code via POST
|
// Login was successful, Microsoft has returned us an authorization code via POST
|
||||||
// Request an access token using authorization code (& client secret) (server side)
|
// Request an access token using authorization code (& client secret) (server side)
|
||||||
if (isset($_POST['code']) && $_POST['state'] == session_id()) {
|
if (isset($_POST['code']) && $_POST['state'] == session_id()) {
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
if ($debug) {
|
if ($debug) {
|
||||||
print "Prior to HMAC calculation pad with zero on the left until 8 characters.<br/>";
|
print "Prior to HMAC calculation pad with zero on the left until 8 characters.<br/>";
|
||||||
print "Calculate sha1 HMAC(Hash-based Message Authentication Code http://en.wikipedia.org/wiki/HMAC).<br/>";
|
print "Calculate sha1 HMAC(Hash-based Message Authentication Code https://en.wikipedia.org/wiki/HMAC).<br/>";
|
||||||
print "hash_hmac ('sha1', $binary, $key)<br/>";
|
print "hash_hmac ('sha1', $binary, $key)<br/>";
|
||||||
}
|
}
|
||||||
$result = hash_hmac ('sha1', $binary, $key);
|
$result = hash_hmac ('sha1', $binary, $key);
|
||||||
|
|||||||
Reference in New Issue
Block a user