From 3bafa07e04473c7cd2d6b3435b02470928e448e5 Mon Sep 17 00:00:00 2001 From: objecttothis <17935339+objecttothis@users.noreply.github.com> Date: Fri, 7 Aug 2026 02:20:01 +0400 Subject: [PATCH] fix(sales): enforce server-side authorization for price changes (#4631) Client-side \"change_price\" flag is UI-only, not trustworthy. Compare submitted price against current cart price server-side and require sales_change_price grant when they differ, else reject with not_authorized error. Signed-off-by: Travis Garrison Co-authored-by: Travis Garrison --- app/Controllers/Sales.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/Controllers/Sales.php b/app/Controllers/Sales.php index 2824a2bc0..b4e96a977 100644 --- a/app/Controllers/Sales.php +++ b/app/Controllers/Sales.php @@ -647,6 +647,14 @@ class Sales extends Secure_Controller return $this->reload($data); } + // sales_change_price grant is enforced server-side here; the UI-only "change_price" flag must not be trusted + $current_price = $this->sale_lib->get_cart()[$line]['price'] ?? null; + $employee_id = $this->employee->get_logged_in_employee_info()->person_id; + if ($current_price !== null && bccomp((string)$price, (string)$current_price, $precision) != 0 && !$this->employee->has_grant('sales_change_price', $employee_id)) { + $data['error'] = lang('Sales.not_authorized'); + return $this->reload($data); + } + $item_location = $this->request->getPost('location', FILTER_SANITIZE_NUMBER_INT); $discounted_total = $this->request->getPost('discounted_total') != '' ? parse_decimals($this->request->getPost('discounted_total') ?? '')