diff --git a/CHANGELOG.md b/CHANGELOG.md index c13dfb3e..d5672b9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ This file documents all notable changes made to ITFlow. +## [26.05.1] Stable Release +- Security Fixes. + ## [26.05] Stable Release ### Bug Fixes - Stripe Payment: Fix adding saved cards on client portal. diff --git a/agent/ajax.php b/agent/ajax.php index b9f2ef0c..c5450e17 100644 --- a/agent/ajax.php +++ b/agent/ajax.php @@ -454,6 +454,12 @@ if (isset($_POST['update_kanban_ticket'])) { foreach ($positions as $position) { $ticket_id = intval($position['ticket_id']); + + // Client perms check + $client_query = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT ticket_client_id FROM tickets WHERE ticket_id = $ticket_id")); + $client_id = intval($client_query['ticket_client_id']); + enforceClientAccess(); + $kanban = intval($position['ticket_order']); // ticket kanban position $status = intval($position['ticket_status']); // ticket statuses $oldStatus = intval($position['ticket_oldStatus']); // ticket old status if moved diff --git a/agent/post/invoice.php b/agent/post/invoice.php index 4efe9213..08353410 100644 --- a/agent/post/invoice.php +++ b/agent/post/invoice.php @@ -542,8 +542,8 @@ if (isset($_GET['email_invoice'])) { $invoice_number = intval($row['invoice_number']); $invoice_scope = sanitizeInput($row['invoice_scope']); $invoice_status = sanitizeInput($row['invoice_status']); - $invoice_date = sanitizeInput($row['invoice_date']); - $invoice_due = sanitizeInput($row['invoice_due']); + $invoice_date = sanitizeInput(validateDate($row['invoice_date'])); + $invoice_due = sanitizeInput(validateDate($row['invoice_due'])); $invoice_amount = floatval($row['invoice_amount']); $invoice_url_key = sanitizeInput($row['invoice_url_key']); $invoice_currency_code = sanitizeInput($row['invoice_currency_code']); diff --git a/agent/post/recurring_invoice.php b/agent/post/recurring_invoice.php index 5ff66e39..9aee5297 100644 --- a/agent/post/recurring_invoice.php +++ b/agent/post/recurring_invoice.php @@ -13,13 +13,13 @@ if (isset($_POST['add_invoice_recurring'])) { enforceUserPermission('module_sales', 2); $invoice_id = intval($_POST['invoice_id']); - $recurring_invoice_frequency = sanitizeInput($_POST['frequency']); + $recurring_invoice_frequency = ($_POST['frequency'] === 'year') ? 'year' : 'month'; $sql = mysqli_query($mysqli,"SELECT * FROM invoices WHERE invoice_id = $invoice_id"); $row = mysqli_fetch_assoc($sql); $invoice_prefix = sanitizeInput($row['invoice_prefix']); $invoice_number = intval($row['invoice_number']); - $invoice_date = sanitizeInput($row['invoice_date']); + $invoice_date = sanitizeInput(validateDate($row['invoice_date'])); $invoice_amount = floatval($row['invoice_amount']); $invoice_currency_code = sanitizeInput($row['invoice_currency_code']); $invoice_scope = sanitizeInput($row['invoice_scope']); @@ -394,7 +394,7 @@ if (isset($_GET['force_recurring'])) { $row = mysqli_fetch_assoc($sql_recurring_invoices); $recurring_invoice_id = intval($row['recurring_invoice_id']); $recurring_invoice_scope = sanitizeInput($row['recurring_invoice_scope']); - $recurring_invoice_frequency = sanitizeInput($row['recurring_invoice_frequency']); + $recurring_invoice_frequency = ($_POST['frequency'] === 'year') ? 'year' : 'month'; $recurring_invoice_status = sanitizeInput($row['recurring_invoice_status']); $recurring_invoice_last_sent = sanitizeInput($row['recurring_invoice_last_sent']); $recurring_invoice_next_date = sanitizeInput($row['recurring_invoice_next_date']); @@ -480,7 +480,7 @@ if (isset($_GET['force_recurring'])) { $invoice_prefix = sanitizeInput($row['invoice_prefix']); $invoice_number = intval($row['invoice_number']); $invoice_scope = sanitizeInput($row['invoice_scope']); - $invoice_date = sanitizeInput($row['invoice_date']); + $invoice_date = sanitizeInput(validateDate($row['invoice_date'])); $invoice_due = sanitizeInput($row['invoice_due']); $invoice_amount = floatval($row['invoice_amount']); $invoice_url_key = sanitizeInput($row['invoice_url_key']); diff --git a/client/post.php b/client/post.php index ed1cdfb8..9d8e0f6d 100644 --- a/client/post.php +++ b/client/post.php @@ -524,12 +524,6 @@ if (isset($_GET['add_payment_by_provider'])) { $contact_extension = preg_replace("/[^0-9]/", '',$row['contact_extension']); $contact_mobile = sanitizeInput(formatPhoneNumber($row['contact_mobile'], $row['contact_mobile_country_code'])); - // Check to make sure saved payment method belongs to logged in client - if ($client_id !== $session_client_id) { - flash_alert("Saved Payment method does not belong to you!", 'danger'); - redirect(); - } - // Get ITFlow company details $sql = mysqli_query($mysqli,"SELECT * FROM companies WHERE company_id = 1"); $row = mysqli_fetch_assoc($sql); @@ -548,7 +542,7 @@ if (isset($_GET['add_payment_by_provider'])) { $config_invoice_from_email = sanitizeInput($config_invoice_from_email); // Get Client Payment Details - $sql = mysqli_query($mysqli, "SELECT * FROM client_saved_payment_methods LEFT JOIN payment_providers ON saved_payment_provider_id = payment_provider_id LEFT JOIN client_payment_provider ON saved_payment_client_id = client_id WHERE saved_payment_id = $saved_payment_id LIMIT 1"); + $sql = mysqli_query($mysqli, "SELECT * FROM client_saved_payment_methods LEFT JOIN payment_providers ON saved_payment_provider_id = payment_provider_id LEFT JOIN client_payment_provider ON saved_payment_client_id = client_id WHERE saved_payment_id = $saved_payment_id AND saved_payment_client_id = $session_client_id LIMIT 1"); $row = mysqli_fetch_assoc($sql); $public_key = sanitizeInput($row['payment_provider_public_key']); @@ -561,9 +555,17 @@ if (isset($_GET['add_payment_by_provider'])) { $payment_provider_client = sanitizeInput($row['payment_provider_client']); $saved_payment_method = sanitizeInput($row['saved_payment_provider_method']); $saved_payment_description = sanitizeInput($row['saved_payment_description']); + $payment_client_id = intval($row['saved_payment_client_id']); // Sanity checks - if (!$payment_provider_client || !$saved_payment_method) { + // Check to make invoice belongs to logged in client + if ($client_id !== $session_client_id) { + flash_alert("Invoice does not belong to you!", 'danger'); + redirect(); + } elseif ($payment_client_id !== $session_client_id) { + flash_alert("Saved Payment method does not belong to you!", 'danger'); + redirect(); + } elseif (!$payment_provider_client || !$saved_payment_method) { flash_alert("Stripe not enabled or no client card saved", 'error'); redirect(); } elseif ($invoice_status !== 'Sent' && $invoice_status !== 'Viewed') { diff --git a/functions.php b/functions.php index ae38369d..c93a79af 100644 --- a/functions.php +++ b/functions.php @@ -1512,8 +1512,8 @@ function logAction($type, $action, $description, $client_id = 0, $entity_id = 0) function logApp($category, $type, $details) { global $mysqli; - $category = substr($category, 0, 200); - $details = substr($details, 0, 1000); + $category = mysqli_real_escape_string($mysqli, substr($category, 0, 200)); + $details = mysqli_real_escape_string($mysqli, substr($details, 0, 1000)); mysqli_query($mysqli, "INSERT INTO app_logs SET app_log_category = '$category', app_log_type = '$type', app_log_details = '$details'"); } @@ -2073,3 +2073,10 @@ function formatDuration($time) { return implode(' ', $parts); } + +function validateDate($date) { + if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) { + return $date; + } + return date('Y-m-d'); // Fallback +} diff --git a/includes/app_version.php b/includes/app_version.php index a89f2f73..dc06d457 100644 --- a/includes/app_version.php +++ b/includes/app_version.php @@ -5,4 +5,4 @@ * Update this file each time we merge develop into master. Format is YY.MM (add a .v if there is more than one release a month. */ -DEFINE("APP_VERSION", "26.05"); +DEFINE("APP_VERSION", "26.05.1");