diff --git a/app/Config/Autoload.php b/app/Config/Autoload.php index 62b24b8d..58edbca1 100755 --- a/app/Config/Autoload.php +++ b/app/Config/Autoload.php @@ -101,6 +101,6 @@ class Autoload extends AutoloadConfig * @phpstan-var list */ public $helpers = ['uuid','session','utility', 'form', 'url', 'oauth', 'fileupload', - 'excel_import_export', 'file', 'drive','ExcelSanitizeHelper', 'api_helper','exception','sms_helper' + 'excel_import_export', 'file', 'drive','ExcelSanitizeHelper', 'api_helper','exception','sms_helper','sanitizeInputArrayAdvanced' ]; } diff --git a/app/Controllers/ClientController.php b/app/Controllers/ClientController.php index 0b6470bc..c5900ca0 100755 --- a/app/Controllers/ClientController.php +++ b/app/Controllers/ClientController.php @@ -736,14 +736,102 @@ class ClientController extends AdminController public function saveDeposit() { + + $rules = [ + + 'amount' => [ + 'rules' => 'required|numeric|greater_than_equal_to[0]', + 'errors' => [ + 'required' => 'Amount is required', + 'numeric' => 'Amount must be a valid number', + 'greater_than_equal_to' => 'Amount cannot be negative', + ] + ], + + 'client_id' => [ + 'rules' => 'required|is_natural_no_zero', + 'errors' => [ + 'required' => 'Client ID is required', + 'is_natural_no_zero' => 'Client ID must be a positive integer', + ] + ], + + 'insurer_id' => [ + 'rules' => 'required|is_natural_no_zero', + 'errors' => [ + 'required' => 'Insurer ID is required', + 'is_natural_no_zero' => 'Insurer ID must be a positive integer', + ] + ], + + 'cd_ac_pk' => [ + 'rules' => 'required|is_natural_no_zero', + 'errors' => [ + 'required' => 'Account PK is required', + 'is_natural_no_zero' => 'Account PK must be a positive integer', + ] + ], + + 'cd_ac_no' => [ + 'rules' => 'required|is_natural_no_zero', + 'errors' => [ + 'required' => 'Account number is required', + 'is_natural_no_zero' => 'must be a positive integer', + ] + ], + + 'sub_type_id' => [ + 'rules' => 'required|is_natural_no_zero', + 'errors' => [ + 'required' => 'Sub type ID is required', + 'is_natural_no_zero' => 'Sub type ID must be a positive integer', + ] + ], + + 'description' => [ + 'rules' => 'required|string|min_length[3]|max_length[255]', + 'errors' => [ + 'required' => 'Description is required', + 'string' => 'Description must be text', + 'min_length' => 'Description must be at least 3 characters', + 'max_length' => 'Description must not exceed 255 characters', + ] + ], + + 'transaction_type' => [ + 'rules' => 'required|in_list[Credit,Debit]', + 'errors' => [ + 'required' => 'Transaction type is required', + 'in_list' => 'Transaction type must be either credit or debit', + ] + ], + + ]; + + + if (! $this->validate($rules)) { + return $this->response + ->setStatusCode(400) + ->setJSON([ + 'status' => 'error', + 'message' => 'Input validation failed', + 'errors' => $this->validator->getErrors() + ]); + } + + //sanitize the post params + $post_data = $this->request->getPost(); + $sanitized_post_data = sanitizeInputArrayAdvanced($post_data); // Retrieve form data from POST request $loggedInUserID = get_session_userid(); + // print_rr($sanitized_post_data);die(); + $client_id = $sanitized_post_data['client_id']; + $insurer_id = $sanitized_post_data['insurer_id']; + $record_date = $sanitized_post_data['record_date']; + $cd_ac_pk = $sanitized_post_data['cd_ac_pk']; + $cd_ac_no = $sanitized_post_data['cd_ac_no']; - $client_id = $this->request->getPost('client_id'); - $insurer_id = $this->request->getPost('insurer_id'); - $record_date = $this->request->getPost('record_date'); - $cd_ac_pk = $this->request->getPost('cd_ac_pk'); - $cd_ac_no = $this->request->getPost('cd_ac_no'); + // $CD_Account_Number = $this->CDMasterModel // ->where('client_id', $client_id) @@ -761,16 +849,16 @@ class ClientController extends AdminController } $data = [ - 'amount' => $this->request->getPost('amount'), - 'sub_type_id' => $this->request->getPost('sub_type_id'), - 'client_id' => $this->request->getPost('client_id'), + 'amount' => $sanitized_post_data['amount'], + 'sub_type_id' => $sanitized_post_data['sub_type_id'], + 'client_id' => $sanitized_post_data['client_id'], 'client_policy_id' => null, 'cd_ac_no' => $cd_ac_no ?? null, 'cd_ac_pk' => $cd_ac_pk ?? null, 'endorsement_no' => null, - 'insurer_id' => $this->request->getPost('insurer_id'), - 'description' => $this->request->getPost('description'), - 'transaction_type' => $this->request->getPost('transaction_type') ?: 'Credit', + 'insurer_id' => $sanitized_post_data['insurer_id'], + 'description' => $sanitized_post_data['description'], + 'transaction_type' => $sanitized_post_data['transaction_type'] ?: 'Credit', 'updated_by' => 1, 'record_date' => $record_date ]; diff --git a/app/Helpers/sanitizeInputArrayAdvanced_helper.php b/app/Helpers/sanitizeInputArrayAdvanced_helper.php new file mode 100644 index 00000000..79d7df9b --- /dev/null +++ b/app/Helpers/sanitizeInputArrayAdvanced_helper.php @@ -0,0 +1,84 @@ + $v) { + + if (is_array($v)) { + $data[$k] = sanitizeInputArrayAdvanced($v, $htmlAllowedFields); + continue; + } + + if (!is_string($v)) { + continue; + } + + // 1. Unicode normalization (prevents homoglyph attacks) + if (class_exists('Normalizer')) { + $v = \Normalizer::normalize($v, \Normalizer::FORM_C); + } + + // 2. Remove NULL bytes & control chars + $v = preg_replace('/[\x00-\x1F\x7F]/u', '', $v); + + // 3. Remove invisible unicode chars (zero width, etc) + $v = preg_replace('/[\x{200B}-\x{200F}\x{202A}-\x{202E}\x{2060}-\x{206F}]/u', '', $v); + + // 4. Decode HTML entities (so hidden payloads are exposed) + $v = html_entity_decode($v, ENT_QUOTES | ENT_HTML5, 'UTF-8'); + + // 5. Trim + $v = trim($v); + + // 6. If this field is NOT allowed to contain HTML → strip aggressively + if (!in_array($k, $htmlAllowedFields, true)) { + + // Remove all tags + $v = strip_tags($v); + + // Kill any leftover JS protocol + $v = preg_replace('/(javascript:|data:|vbscript:)/i', '', $v); + + } else { + // This is HTML-allowed field → run HTML sanitizer + $v = sanitizeTrustedHtml($v); + } + + $data[$k] = $v; + } + + return $data; +} + +function sanitizeTrustedHtml(string $html): string +{ + // Allowed tags for email templates + $allowedTags = '