- Merge Config and Core File Changes 4.6.3 > 4.6.4
- Merge Config and Core File Changes 4.6.4 > 4.7.0
- Added app\Config\WorkerMode.php
- Merge Config and Core File Changes Not previously merged
- Added app\Config\Hostnames.php
- Corrected incorrect CSS property used in invoice.php view.
- Corrected unknown CSS properties used in register.php view.
- Used shorthand CSS in debug.css
- Corrected indentation in barcode_sheet.php view.
- Corrected indentation in footer.php view.
- Corrected indentation in invoice_email.php view.
- Replaced obsolete attributes with CSS style attributes in barcode_sheet.php
- Replaced obsolete attribute in error_exception.php
- Replaced obsolete attribute in invoice_email.php
- Replaced obsolete attribute in quote_email.php
- Replaced obsolete attributes in work_order_email.php
- Fixed indentation in system_info.php
- Replaced <strong> tag outside <p> tags, which isn't allowed, with style attributes.
- Simplified js return logic and indentation fixes in tax_categories.php
- Simplified js return logic in tax_codes.php
- Simplified js return logic in tax_jurisdictions.php
- Removed unnecessary labels in manage views.
- Rewrite JavaScript function and PHP to be more readable in bar.php, hbar.php, line.php and pie.php
- Added type declarations, return types and an import to app\Config\Services
- Updated Attribute.php parameter type
- Updated Receiving_lib.php parameter type
- Updated Receivings.php parameter types and updated PHPdocs
- Updated tabular_helper.php parameter types and updated PHPdocs
- Added type declarations and corrected PHPdocs in url_helper.php
- Added return types to functions
- Revert $objectSrc value in ContentSecurityPolicy.php
- Correct return type in Customer->get_stats()
- Correct return type in Item->get_info_by_id_or_number()
- Correct misspelling in border-spacing
- Added missing css style semicolons
- Resolve operator precedence ambiguity.
- Resolve column mismatch.
- Added missing escaping in view.
- Updated requirement for PHP 8.2
- Resolve unresolved conflicts
- Added PHP 8.2 requirement to the README.md
- Fixed bugs in display of UI
- Fixed duplicated `>` in app\Views\Expenses\manage.php
- Removed excess whitespace at the end of some lines in table_filter_persistence.php
- Added missing `>` in app\Views\Expenses\manage.php
- Corrected grammar in PHPdoc in table_filter_persistence.php
- Remove bug causing `\` to be injected into the new giftcard value
- Fix bug causing DROPDOWN Attribute Values to not save correctly
- Added check for null in $normalizedItemId
- Removing < PHP 8.2 from linting and tests
- Update Linter to not include PHP 8.2 and 8.1
- Remove PHP 8.1 unit test cycle.
- Update Bug Report Template
- Update Composer files for CodeIgniter 4.7.2
- Updated INSTALL.md to reflect changes.
---------
Signed-off-by: objec <objecttothis@gmail.com>
* Fix SQL injection in suggestions column configuration
The suggestions_first_column, suggestions_second_column, and
suggestions_third_column configuration values were concatenated
directly into SQL SELECT statements without validation, allowing
SQL injection attacks through the item search suggestions.
Changes:
- Add whitelist validation in Config controller to only allow
valid column names (name, item_number, description, cost_price,
unit_price)
- Add defensive validation in Item model's get_search_suggestion_format()
and get_search_suggestion_label() methods
- Default invalid values to 'name' column for safety
- Add unit tests to verify malicious inputs are rejected
This is a critical security fix as attackers with config permissions
could inject arbitrary SQL through these configuration fields.
Vulnerability reported as additional injection point in bug report.
* Refactor: Move allowed suggestions columns to Item model constants
Extract the list of valid suggestion columns into two constants in the Item model for better cohesion:
- ALLOWED_SUGGESTIONS_COLUMNS: valid column names
- ALLOWED_SUGGESTIONS_COLUMNS_WITH_EMPTY: includes empty string for config validation
This consolidates the validation logic in one place and makes it reusable across Config controller and Item model.
* Address PR review comments: improve validation and code quality
Changes:
- Use camelCase naming for validateSuggestionsColumn() method (PSR-12)
- Add field-aware validation with different fallbacks for first vs other columns
- Handle non-string POST input by checking is_string() before validation
- Refactor duplicate validation logic into suggestionColumnIsAllowed() helper
- Use consistent camelCase variable names ($suggestionsFirstColumn)
- Update tests to validate constants and behavior rather than implementation
- Tests now focus on security properties of the allowlist itself
The validation now properly handles:
- First column: defaults to 'name' when invalid
- Second/Third columns: defaults to '' (empty) when invalid
- Non-string inputs: treated as invalid with appropriate fallback
---------
Co-authored-by: Ollama <ollama@steganos.dev>
The bulk edit function iterated over all $_POST keys without a whitelist,
allowing authenticated users to inject arbitrary database columns (e.g.,
cost_price, deleted, item_type) into the update query. This bypassed
CodeIgniter 4's $allowedFields protection since Query Builder was used
directly.
Fix: Add ALLOWED_BULK_EDIT_FIELDS constant to Item model defining the
explicit whitelist of fields that can be bulk-updated. Use this constant
in the controller instead of iterating over $_POST directly.
Fields allowed: name, category, supplier_id, cost_price, unit_price,
reorder_level, description, allow_alt_description, is_serialized
Security impact: High (CVSS 8.1) - Could allow price manipulation and
data integrity violations.
The previous SQL injection fix (GHSA-hmjv-wm3j-pfhw) used named parameter
syntax :search: with having(), but CodeIgniter 4's having() method does
not support named parameters. This caused the query to fail.
The fix uses havingLike() which properly:
- Escapes the search value to prevent SQL injection
- Handles the LIKE clause construction internally (wraps value with %)
- Works correctly with HAVING clauses for aggregated columns
This maintains the security fix while actually working on CI4.
Parameterize LIKE queries in HAVING clause to prevent SQL injection
when search_custom filter is enabled. Also sanitize search parameter
input at controller level for defense-in-depth.
Fixes vulnerability where user input was directly interpolated into
SQL queries without sanitization.
* Improve code style and PSR-12 compliance
- refactored code formatting to adhere to PSR-12 guidelines
- standardized coding conventions across the codebase
- added missing framework files and reverted markup changes
- reformatted arrays for enhanced readability
- updated language files for consistent styling and clarity
- minor miscellaneous improvements
* Remove HtmlPurifier calls
- All calls to Services::htmlPurifier()->purify() removed from data received from view.
- Bootstrap and bootswatch bump in package-lock.json
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Pre-view filtering Items Controller
- Refactored code for clarity
- Created and called sanitization functions.
- Sanitize TEXT type Attributes before being sent to the view.
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Pre-view filtering Customers Controller
- Refactored code for clarity
- Replaced == with === operator to prevent type juggling
- Added Sanitization of Customer data before being sent to the view
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Bump bootstrap-table to 1.23.1
- Bump bootstrap-table to 1.23.1 in attempt to resolve issue with sticky headers
- Sanitize attribute data in tables
- Sanitize item data with controller function.
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Pre-view filtering Items Controller
- Refactored code for clarity
- Created and called sanitization functions.
- Sanitize TEXT type Attributes before being sent to the view.
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Sanitize Item data
- Sanitize category and item_number before display in forms.
- refactor check in pic_filename for empty to be best practices compliant.
- Added TODO
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Minor changes
- Refactored for code clarity.
- Removed extra blank lines.
- Minor reformatting.
- Added PHPdocs
- bumped bootstrap-table to 1.23.2
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Pre-view filtering Items Controller
- Refactored code for clarity
- Created and called sanitization functions.
- Sanitize TEXT type Attributes before being sent to the view.
Signed-off-by: objecttothis <objecttothis@gmail.com>
* Sanitize Item data
- Sanitize category and item_number before display in forms.
- refactor check in pic_filename for empty to be best practices compliant.
- Added TODO
Signed-off-by: objecttothis <objecttothis@gmail.com>
---------
Signed-off-by: objecttothis <objecttothis@gmail.com>
Co-authored-by: objecttothis <objecttothis@gmail.com>
- Added TODO where we need to convert to querybuilder
- Converted to switch statement.
- Removed unnecessary local variable
- Replaced Qualifiers with imports
- Replaced isset() call with null coalescing operator
- Replaced strpos function calls in if statements with str_contains calls
- Removed unnecessary leading \ in use statement
- Replaced deprecated functions
- Updated PHPdocs to match function signature
- Added missing type declarations
- Made class variables private.
- Explicitly declared dynamic properties
- use https:// links instead of http://
- Fixed type error from sending null when editing transactions
- Fixed Search Suggestion function name in Employees, Persons, Suppliers controller
- Fixed function name on Receivings Controller
Signed-off-by: objecttothis <objecttothis@gmail.com>
- Added filtering to decimals which may have different comma separator
- Added formatting of decimals before concatenating into string
- Cast int to string in form_hidden() call
Signed-off-by: objecttothis <objecttothis@gmail.com>
- Made view CI form helper function call format uniform.
- replaced calls to array() with []
- Placed { on its own line
- Removed empty lines where there shouldn't be any.
- Replaced text/javascript with application/javascript as the former is deprecated
Attributes: Noticed log_message() being called with uppercase letters in the level which causes errors in the system; Customers: improved the layout of the stats page in the information dialog issue 3892; Items: got csv import working issue 3896 and bulk edits working - barcode generation does not work yet.
- Removed unnecessary ReflectionException in PHPdoc
- Corrected return details of insert function
- Replaced deprecated class
- Removed Inventory model's insert function because it wasn't providing functionality that the Model class wasn't.
- Corrected the calling method signature for Inventory->insert()
- Added missing PHPdocs
- Corrected Syntax
- Added noinspection parameters to PHPdoc for AJAX called functions
- Added missing function return types
- Added missing parameter types
- Added public keyword to functions without visibility modifier
- Corrected incorrectly formatted PHPdocs
- Added public to constants and functions missing a visibility keyword
- Replaced TRUE/FALSE constants with true/false keywords
- Replaced NULL constant with null keyword
- Replaced `<?php echo` in views with shortened `<?=`
- Added missing variable declaration
- Added missing function return type in declaration
- replaced `== true`, `== false`, `=== true` and `=== false` in if statements with simplified forms
- Declared variable in view coming down from controller
- refactored javascript variable name to remove duplicate declaration warning
- Import missing class
- when the payments array was folded into sale_data there was an earlier payments[] reference in the foreach loop that didn't get folded in.
- Update PHPdoc
- Added ::class to remove polymorphic call warning
- Removed unreachable 'break;' statement after return statement.
- Added missing return type
- fixed missing assignment of mailchimp_api_key