tests: fix SecurityTest fatal TypeError — update searchTheses call to use array params

SecurityTest::Test1 was calling $db->searchTheses($string) with a plain
string, but searchTheses() was refactored to require array $params when
the tag M2M work landed.  This caused an immediate PHP fatal TypeError
before any SQL ever ran, killing the entire Security test suite with
exit code 255 and masking all three tests.

Fix: pass each malicious payload via ['query' => $string] which is the
correct API and properly exercises the parameterised query path through
validateSearchParams() + buildSearchConditions().  Added a clarifying
comment explaining why the array form is required.

All 4 test suites now pass:
  - Database (Unit):   7/7
  - Rate Limit (Unit): 5/5
  - Search (Integration): 6/6
  - Security:          3/3
This commit is contained in:
Pontoporeia
2026-03-26 18:54:20 +01:00
parent e4be230a04
commit b12ae73e91
5 changed files with 14 additions and 6 deletions

View File

@@ -317,6 +317,10 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
--- ---
## Fixes
- [x] Fix `tests/Security/SecurityTest.php`: update SQL injection test to call `searchTheses(['query' => $string])` instead of bare string — `searchTheses()` signature was updated to `array $params` but the test was never updated, causing a fatal `TypeError` that prevented the security suite from running at all
## Pending ## Pending
- [x] Add flake.nix for Nix-based PHP dev environment - [x] Add flake.nix for Nix-based PHP dev environment

View File

@@ -1 +1 @@
[1770895832] [1774547615,1774547646]

View File

@@ -1 +0,0 @@
[1774354709]

Binary file not shown.

View File

@@ -13,6 +13,10 @@ try {
$db = Database::getInstance(); $db = Database::getInstance();
// Test 1: SQL Injection in search // Test 1: SQL Injection in search
// searchTheses() takes an array of validated params; the 'query' key is the
// free-text search field that users control. Each malicious string must
// be passed as ['query' => $string] to exercise the actual parameterised
// query path rather than triggering a PHP TypeError before any SQL runs.
echo "Test 1: SQL Injection Protection (Search)\n"; echo "Test 1: SQL Injection Protection (Search)\n";
$maliciousQueries = [ $maliciousQueries = [
"' OR '1'='1", "' OR '1'='1",
@@ -23,11 +27,12 @@ try {
foreach ($maliciousQueries as $query) { foreach ($maliciousQueries as $query) {
try { try {
$results = $db->searchTheses($query); $results = $db->searchTheses(['query' => $query]);
echo " ✓ Blocked: " . substr($query, 0, 30) . "...\n"; // Should return a (possibly empty) result set without throwing
echo " ✓ Handled safely: " . substr($query, 0, 40) . "\n";
} catch (Exception $e) { } catch (Exception $e) {
// Exception is also acceptable (query blocked) // A thrown exception is also acceptable (query rejected upstream)
echo " ✓ Exception: " . substr($query, 0, 30) . "...\n"; echo " ✓ Exception (safe): " . substr($query, 0, 40) . "\n";
} }
} }
echo "✓ PASS: SQL injection attempts handled safely\n\n"; echo "✓ PASS: SQL injection attempts handled safely\n\n";