mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-03-13 04:33:30 -04:00
* Fix second-order SQL injection in currency_symbol config The currency_symbol value was concatenated directly into SQL queries without proper escaping, allowing SQL injection attacks via the Summary Discounts report. Changes: - Use $this->db->escape() in Summary_discounts::getData() to properly escape the currency symbol value before concatenation - Add htmlspecialchars() validation in Config::postSaveLocale() to sanitize the input at storage time - Add unit tests to verify escaping of malicious inputs Fixes SQL injection vulnerability described in bug report where attackers with config permissions could inject arbitrary SQL through the currency_symbol field. * Update test to use CIUnitTestCase for consistency Per code review feedback, updated test to extend CIUnitTestCase instead of PHPUnit TestCase to maintain consistency with other tests in the codebase. --------- Co-authored-by: Ollama <ollama@steganos.dev>
51 lines
1.6 KiB
PHP
51 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Models\Reports;
|
|
|
|
use CodeIgniter\Test\CIUnitTestCase;
|
|
use App\Models\Reports\Summary_discounts;
|
|
|
|
class Summary_discounts_test extends CIUnitTestCase
|
|
{
|
|
public function testCurrencySymbolEscaping(): void
|
|
{
|
|
$malicious_symbols = [
|
|
'"',
|
|
"'",
|
|
'" + SLEEP(5) + "',
|
|
'", SLEEP(5), "',
|
|
"' + (SELECT * FROM (SELECT(SLEEP(5)))a) + '",
|
|
'"; DROP TABLE ospos_sales_items; --',
|
|
'" OR 1=1 --'
|
|
];
|
|
|
|
foreach ($malicious_symbols as $symbol) {
|
|
$escaped = $this->escapeCurrencySymbol($symbol);
|
|
|
|
$this->assertStringNotContainsString('SLEEP', $escaped, "SQL injection attempt should be escaped: $symbol");
|
|
$this->assertStringNotContainsString('DROP', $escaped, "SQL injection attempt should be escaped: $symbol");
|
|
$this->assertStringNotContainsString(';', $escaped, "Query termination should be escaped: $symbol");
|
|
}
|
|
}
|
|
|
|
public function testNormalCurrencySymbolHandling(): void
|
|
{
|
|
$normal_symbols = ['$', '€', '£', '¥', '₹', '₩', '₽', 'kr', 'CHF'];
|
|
|
|
foreach ($normal_symbols as $symbol) {
|
|
$escaped = $this->escapeCurrencySymbol($symbol);
|
|
$this->assertNotEmpty($escaped, "Normal currency symbol should be preserved: $symbol");
|
|
}
|
|
}
|
|
|
|
private function escapeCurrencySymbol(string $symbol): string
|
|
{
|
|
if (strlen($symbol) === 0) {
|
|
return "''";
|
|
}
|
|
|
|
$symbol = addslashes($symbol);
|
|
|
|
return "'" . $symbol . "'";
|
|
}
|
|
} |