Commit Graph
11 Commits
Author SHA1 Message Date
Hamza-Ayed e03b9c30d5 Update: 2026-07-25 18:43:44 2026-07-25 18:43:44 +03:00
Hamza-Ayed 8d3e63d1c7 Update: 2026-07-25 18:40:38 2026-07-25 18:40:38 +03:00
Hamza-Ayed 4bbc687c15 Update: 2026-07-25 18:28:30 2026-07-25 18:28:31 +03:00
Hamza-AyedandClaude Opus 5 c9b4d14da6 Route account lookups through the blind index and keep it fresh on write
These are the paths that must stop depending on deterministic encryption
before storage can move to AES-GCM. Each keeps its original ciphertext
comparison in the same statement, so behaviour is unchanged today and no
account becomes unreachable during the transition.

Lookups:
- auth/login.php — passenger sign-in matched the raw value against the
  encrypted column, which only works because encryptData() is CBC with a
  fixed IV.
- auth/passenger/register.php and auth/driver/register.php — duplicate
  detection. Without the index these would stop detecting existing accounts
  under GCM and allow the same phone to register twice.

Writes now populate the index in the same statement as the value:
- both registration paths write phone/email/name indexes with the row;
  driver indexes are computed before the encryption pass, since the raw
  values are unavailable afterwards.
- passenger profile update and admin driver update refresh the index when
  the underlying field changes. For the composite name index the untouched
  half is read back from the row.

Adds --audit to the backfill script: recomputes every index from its
encrypted value and reports missing or stale entries. Drift here is silent
by nature — it surfaces only when a real search fails.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 16:04:40 +03:00
Hamza-AyedandClaude Opus 5 6802026dbd Add blind-index search layer; fix captain detail 200-with-empty-body
Searching encrypted columns currently works only because encryptData() is
AES-CBC with a fixed IV, i.e. deterministic. That determinism is what leaks
equality and shared prefixes, and it is why moving storage to AES-GCM would
break every lookup. This separates the two concerns.

- core/Security/BlindIndex.php: HMAC-SHA256 over a normalised value, keyed by
  a secret pepper. Phone numbers have a small keyspace, so a bare SHA-256
  would be reversible by enumeration; the pepper lives in the environment, not
  the database. The scope string includes table and field so the same number
  does not produce a matching index across tables.
  Normalisation unifies local/international phone forms, lowercases emails and
  folds Arabic alef/ya/ta-marbuta and diacritics for names.
- migrations/: nullable *_bidx columns plus indexes, and the missing
  adminUser.status/approved_by/approved_at columns that admin approvals need.
- scripts/backfill_blind_index.php: restartable, batched, --dry-run capable,
  touches only index columns.
- Admin lookups by phone/email now match the index, keeping the old ciphertext
  comparison in the same query so search keeps working until the backfill runs.
  bootstrap exposes $blindIndex as null when no pepper is configured.

Also: AdminCaptain/getCaptainDetailsById.php selected driver.education, a
column absent from this schema. The PDOException was uncaught, so the client
received an empty body with HTTP 200 — the "non-JSON response" seen when
opening a captain. It now omits the column, catches the error, reports it as
JSON, and requires an admin role.

Console: opening any sidebar section refetches its data instead of showing
what was loaded when the console started.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 15:16:09 +03:00
Hamza-Ayed 42f6d33efd Update: 2026-07-25 14:44:30 2026-07-25 14:44:30 +03:00
Hamza-Ayed 2152d34a8e fix: resolve stale price display in driver ratings and remove misleading discount UI in rider ratings 2026-07-09 04:48:19 +03:00
Hamza-Ayed 72eeb24cd7 Fix #18: Exception leak remediation across 87 PHP files
- Replaced all client-facing $e->getMessage() with generic error messages
- Added error_log() with filename prefix to all catch blocks
- Covered jsonError(), echo, and json_encode() response patterns
- Also fixed 2 remaining display_errors=1 and add_invoice.php leak
- Script-assisted fix for 75 files, manual fix for 12 remaining edge cases
2026-06-17 07:48:31 +03:00
Hamza-Ayed 04943e3d52 Update: 2026-06-15 19:39:21 2026-06-15 19:39:21 +03:00
Hamza-Ayed f907212c57 Update: 2026-06-12 20:40:40 2026-06-12 20:40:40 +03:00
Hamza-Ayed d8901e1a87 first commit 2026-06-09 08:40:31 +03:00