Blind SQL injection fix (#3284)

This commit is contained in:
jekkos
2024-09-19 00:55:49 +02:00
committed by jekkos
parent 72f147074d
commit 0f4d06af61
13 changed files with 135 additions and 118 deletions

View File

@@ -41,7 +41,7 @@ class Attributes extends Secure_Controller
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(ATTRIBUTE_DEFINITION_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'definition_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$attributes = $this->attribute->search($search, $limit, $offset, $sort, $order);

View File

@@ -46,7 +46,7 @@ class Cashups extends Secure_Controller
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(CASHUPS_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'cashup_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [
'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS), //TODO: Is this the best way to filter dates

View File

@@ -90,7 +90,7 @@ class Customers extends Persons
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(CUSTOMER_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$customers = $this->customer->search($search, $limit, $offset, $sort, $order);

View File

@@ -30,7 +30,7 @@ class Employees extends Persons
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(PERSON_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$employees = $this->employee->search($search, $limit, $offset, $sort, $order);

View File

@@ -48,7 +48,7 @@ class Expenses extends Secure_Controller
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(EXPENSE_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [
'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),

View File

@@ -34,7 +34,7 @@ class Expenses_categories extends Secure_Controller //TODO: Is this class ever u
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(EXPENSE_CATEGORY_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_category_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$expense_categories = $this->expense_category->search($search, $limit, $offset, $sort, $order);

View File

@@ -35,7 +35,7 @@ class Giftcards extends Secure_Controller
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(GIFTCARD_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'giftcard_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$giftcards = $this->giftcard->search($search, $limit, $offset, $sort, $order);

View File

@@ -79,7 +79,7 @@ class Item_kits extends Secure_Controller
$search = $this->request->getGet('search') ?? '';
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(ITEM_KIT_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'item_kit_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$item_kits = $this->item_kit->search($search, $limit, $offset, $sort, $order);

View File

@@ -97,7 +97,7 @@ class Items extends Secure_Controller
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(ITEM_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'item_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$this->item_lib->set_item_location($this->request->getGet('stock_location'));

View File

@@ -136,7 +136,7 @@ class Sales extends Secure_Controller
$search = $this->request->getGet('search', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(SALES_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'sale_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [

View File

@@ -82,6 +82,11 @@ class Secure_Controller extends BaseController
view('viewData', $this->global_view_data);
}
public function sanitizeSortColumn($headers, $field, $default): string
{
return $field != null && in_array($field, array_keys(array_merge(...$headers))) ? $field : $default;
}
/**
* AJAX function used to confirm whether values sent in the request are numeric
* @return void

View File

@@ -48,7 +48,7 @@ class Suppliers extends Persons
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$sort = $this->sanitizeSortColumn(SUPPLIER_HEADERS, $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$suppliers = $this->supplier->search($search, $limit, $offset, $sort, $order);

View File

@@ -16,11 +16,11 @@ use Config\Services;
/**
* Basic tabular headers function
*/
function transform_headers_readonly(array $array): string //TODO: $array needs to be refactored to a new name. Perhaps $headers?
function transform_headers_readonly(array $headers): string
{
$result = [];
foreach($array as $key => $value)
foreach($headers as $key => $value)
{
$result[] = ['field' => $key, 'title' => $value, 'sortable' => $value != '', 'switchable' => !preg_match('(^$|&nbsp)', $value)];
}
@@ -31,21 +31,21 @@ function transform_headers_readonly(array $array): string //TODO: $array needs t
/**
* Basic tabular headers function
*/
function transform_headers(array $array, bool $readonly = false, bool $editable = true): string //TODO: $array needs to be refactored to a new name. Perhaps $headers?
function transform_headers(array $headers, bool $readonly = false, bool $editable = true): string //TODO: $array needs to be refactored to a new name. Perhaps $headers?
{
$result = [];
if(!$readonly)
{
$array = array_merge ([['checkbox' => 'select', 'sortable' => false]], $array);
$headers = array_merge ([['checkbox' => 'select', 'sortable' => false]], $headers);
}
if($editable)
{
$array[] = ['edit' => ''];
$headers[] = ['edit' => ''];
}
foreach($array as $element) //TODO: This might be clearer to refactor this to `foreach($headers as $header)`
foreach($headers as $element) //TODO: This might be clearer to refactor this to `foreach($headers as $header)`
{
reset($element);
$result[] = [
@@ -63,20 +63,22 @@ function transform_headers(array $array, bool $readonly = false, bool $editable
return json_encode($result);
}
define("SALES_HEADERS", [
['sale_id' => lang('Common.id')],
['sale_time' => lang('Sales.sale_time')],
['customer_name' => lang('Customers.customer')],
['amount_due' => lang('Sales.amount_due')],
['amount_tendered' => lang('Sales.amount_tendered')],
['change_due' => lang('Sales.change_due')],
['payment_type' => lang('Sales.payment_type')]
]);
/**
* Get the header for the sales tabular view
*/
function get_sales_manage_table_headers(): string
{
$headers = [
['sale_id' => lang('Common.id')],
['sale_time' => lang('Sales.sale_time')],
['customer_name' => lang('Customers.customer')],
['amount_due' => lang('Sales.amount_due')],
['amount_tendered' => lang('Sales.amount_tendered')],
['change_due' => lang('Sales.change_due')],
['payment_type' => lang('Sales.payment_type')]
];
$headers = SALES_HEADERS;
$config = config(OSPOS::class)->settings;
if($config['invoice_enable'])
@@ -187,18 +189,20 @@ function get_sales_manage_payments_summary(array $payments): string
return $table;
}
define('PERSON_HEADERS', [
['people.person_id' => lang('Common.id')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['email' => lang('Common.email')],
['phone_number' => lang('Common.phone_number')]
]);
/**
* Get the header for the people tabular view
*/
function get_people_manage_table_headers(): string
{
$headers = [
['people.person_id' => lang('Common.id')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['email' => lang('Common.email')],
['phone_number' => lang('Common.phone_number')]
];
$headers = PERSON_HEADERS;
$employee = model(Employee::class);
$session = session();
@@ -247,19 +251,21 @@ function get_person_data_row(object $person): array
];
}
define('CUSTOMER_HEADERS', [
['people.person_id' => lang('Common.id')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['email' => lang('Common.email')],
['phone_number' => lang('Common.phone_number')],
['total' => lang('Common.total_spent'), 'sortable' => false]
]);
/**
* Get the header for the customer tabular view
*/
function get_customer_manage_table_headers(): string
{
$headers = [
['people.person_id' => lang('Common.id')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['email' => lang('Common.email')],
['phone_number' => lang('Common.phone_number')],
['total' => lang('Common.total_spent'), 'sortable' => false]
];
$headers = CUSTOMER_HEADERS;
$employee = model(Employee::class);
$session = session();
@@ -309,21 +315,23 @@ function get_customer_data_row(object $person, object $stats): array
];
}
define('SUPPLIER_HEADERS', [
['people.person_id' => lang('Common.id')],
['company_name' => lang('Suppliers.company_name')],
['agency_name' => lang('Suppliers.agency_name')],
['category' => lang('Suppliers.category')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['email' => lang('Common.email')],
['phone_number' => lang('Common.phone_number')]
]);
/**
* Get the header for the suppliers tabular view
*/
function get_suppliers_manage_table_headers(): string
{
$headers = [
['people.person_id' => lang('Common.id')],
['company_name' => lang('Suppliers.company_name')],
['agency_name' => lang('Suppliers.agency_name')],
['category' => lang('Suppliers.category')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['email' => lang('Common.email')],
['phone_number' => lang('Common.phone_number')]
];
$headers = SUPPLIER_HEADERS;
$employee = model(Employee::class);
$session = session();
@@ -375,6 +383,17 @@ function get_supplier_data_row(object $supplier): array
];
}
define('ITEM_HEADERS', [
['items.item_id' => lang('Common.id')],
['item_number' => lang('Items.item_number')],
['name' => lang('Items.name')],
['category' => lang('Items.category')],
['company_name' => lang('Suppliers.company_name')],
['cost_price' => lang('Items.cost_price')],
['unit_price' => lang('Items.unit_price')],
['quantity' => lang('Items.quantity')]
]);
/**
* Get the header for the items tabular view
*/
@@ -384,16 +403,7 @@ function get_items_manage_table_headers(): string
$config = config(OSPOS::class)->settings;
$definition_names = $attribute->get_definitions_by_flags($attribute::SHOW_IN_ITEMS); //TODO: this should be made into a constant in constants.php
$headers = [
['items.item_id' => lang('Common.id')],
['item_number' => lang('Items.item_number')],
['name' => lang('Items.name')],
['category' => lang('Items.category')],
['company_name' => lang('Suppliers.company_name')],
['cost_price' => lang('Items.cost_price')],
['unit_price' => lang('Items.unit_price')],
['quantity' => lang('Items.quantity')]
];
$headers = ITEM_HEADERS;
if($config['use_destination_based_tax'])
{
@@ -523,20 +533,20 @@ function get_item_data_row(object $item): array
return $columns + expand_attribute_values($definition_names, (array) $item) + $icons;
}
define('GIFTCARD_HEADERS', [
['giftcard_id' => lang('Common.id')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['giftcard_number' => lang('Giftcards.giftcard_number')],
['value' => lang('Giftcards.card_value')]
]);
/**
* Get the header for the giftcard tabular view
*/
function get_giftcards_manage_table_headers(): string
{
$headers = [
['giftcard_id' => lang('Common.id')],
['last_name' => lang('Common.last_name')],
['first_name' => lang('Common.first_name')],
['giftcard_number' => lang('Giftcards.giftcard_number')],
['value' => lang('Giftcards.card_value')]
];
return transform_headers($headers);
return transform_headers(GIFTCARD_HEADERS);
}
/**
@@ -564,21 +574,21 @@ function get_giftcard_data_row(object $giftcard): array
];
}
define('ITEM_KIT_HEADERS', [
['item_kit_id' => lang('Item_kits.kit')],
['item_kit_number' => lang('Item_kits.item_kit_number')],
['name' => lang('Item_kits.name')],
['description' => lang('Item_kits.description')],
['total_cost_price' => lang('Items.cost_price'), 'sortable' => false],
['total_unit_price' => lang('Items.unit_price'), 'sortable' => false]
]);
/**
* Get the header for the item kits tabular view
*/
function get_item_kits_manage_table_headers(): string
{
$headers = [
['item_kit_id' => lang('Item_kits.kit')],
['item_kit_number' => lang('Item_kits.item_kit_number')],
['name' => lang('Item_kits.name')],
['description' => lang('Item_kits.description')],
['total_cost_price' => lang('Items.cost_price'), 'sortable' => false],
['total_unit_price' => lang('Items.unit_price'), 'sortable' => false]
];
return transform_headers($headers);
return transform_headers(ITEM_KIT_HEADERS);
}
/**
@@ -662,20 +672,20 @@ function expand_attribute_values(array $definition_names, array $row): array
return $attribute_values;
}
define('ATTRIBUTE_DEFINITION_HEADERS', [
['definition_id' => lang('Attributes.definition_id')],
['definition_name' => lang('Attributes.definition_name')],
['definition_type' => lang('Attributes.definition_type')],
['definition_flags' => lang('Attributes.definition_flags')],
['definition_group' => lang('Attributes.definition_group')],
]);
/**
* @return string
*/
function get_attribute_definition_manage_table_headers(): string
{
$headers = [
['definition_id' => lang('Attributes.definition_id')],
['definition_name' => lang('Attributes.definition_name')],
['definition_type' => lang('Attributes.definition_type')],
['definition_flags' => lang('Attributes.definition_flags')],
['definition_group' => lang('Attributes.definition_group')],
];
return transform_headers($headers);
return transform_headers(ATTRIBUTE_DEFINITION_HEADERS);
}
/**
@@ -719,18 +729,18 @@ function get_attribute_definition_data_row(object $attribute_row): array
];
}
define('EXPENSE_CATEGORY_HEADERS', [
['expense_category_id' => lang('Expenses_categories.category_id')],
['category_name' => lang('Expenses_categories.name')],
['category_description' => lang('Expenses_categories.description')]
]);
/**
* Get the header for the expense categories tabular view
*/
function get_expense_category_manage_table_headers(): string
{
$headers = [
['expense_category_id' => lang('Expenses_categories.category_id')],
['category_name' => lang('Expenses_categories.name')],
['category_description' => lang('Expenses_categories.description')]
];
return transform_headers($headers);
return transform_headers(EXPENSE_CATEGORY_HEADERS);
}
/**
@@ -756,26 +766,25 @@ function get_expense_category_data_row(object $expense_category): array
];
}
define('EXPENSE_HEADERS', [
['expense_id' => lang('Expenses.expense_id')],
['date' => lang('Expenses.date')],
['supplier_name' => lang('Expenses.supplier_name')],
['supplier_tax_code' => lang('Expenses.supplier_tax_code')],
['amount' => lang('Expenses.amount')],
['tax_amount' => lang('Expenses.tax_amount')],
['payment_type' => lang('Expenses.payment')],
['category_name' => lang('Expenses_categories.name')],
['description' => lang('Expenses.description')],
['created_by' => lang('Expenses.employee')]
]);
/**
* Get the header for the expenses tabular view
*/
function get_expenses_manage_table_headers(): string
{
$headers = [
['expense_id' => lang('Expenses.expense_id')],
['date' => lang('Expenses.date')],
['supplier_name' => lang('Expenses.supplier_name')],
['supplier_tax_code' => lang('Expenses.supplier_tax_code')],
['amount' => lang('Expenses.amount')],
['tax_amount' => lang('Expenses.tax_amount')],
['payment_type' => lang('Expenses.payment')],
['category_name' => lang('Expenses_categories.name')],
['description' => lang('Expenses.description')],
['created_by' => lang('Expenses.employee')]
];
return transform_headers($headers);
return transform_headers(EXPENSE_HEADERS);
}
/**
@@ -849,13 +858,7 @@ function get_expenses_manage_payments_summary(array $payments, ResultInterface $
return $table;
}
/**
* Get the header for the cashup tabular view
*/
function get_cashups_manage_table_headers(): string
{
$headers = [
define('CASHUPS_HEADERS', [
['cashup_id' => lang('Cashups.id')],
['open_date' => lang('Cashups.opened_date')],
['open_employee_id' => lang('Cashups.open_employee')],
@@ -869,7 +872,16 @@ function get_cashups_manage_table_headers(): string
['closed_amount_card' => lang('Cashups.closed_amount_card')],
['closed_amount_check' => lang('Cashups.closed_amount_check')],
['closed_amount_total' => lang('Cashups.closed_amount_total')]
];
]
);
/**
* Get the header for the cashup tabular view
*/
function get_cashups_manage_table_headers(): string
{
$headers = CASHUPS_HEADERS;
return transform_headers($headers);
}