Close the remaining ciphertext joins and a SQL injection in email verification
- Customer-service notes joined to the account by comparing encrypted phone columns. Both notes tables now carry phone_key, written when a note is saved, and the three joins match on it. - The email_verifications join was comparing a plaintext column against an encrypted one, so it never matched and `verified` was always NULL in both passenger and driver sign-in. It is now resolved in PHP against the decrypted address, which fixes a pre-existing bug rather than only preparing for GCM. - auth/sendVerifyEmail.php built all three of its statements by interpolating the request values into SQL. Any caller could inject through the email or token field. Now parameterised. - serviceapp/register.php duplicate detection consults the users indexes and writes them with the row. Sweep confirms no join or lookup compares two encrypted columns any more. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
35a66935aa
commit
2135edcf43
@@ -35,14 +35,26 @@ try {
|
||||
|
||||
// 1. التحقق من عدم وجود الحساب مسبقاً (عن طريق البريد الإلكتروني، الهاتف أو البصمة)
|
||||
$fpHash = hash('sha256', $fingerprint);
|
||||
$check = $con->prepare("SELECT id FROM users WHERE email = ? OR phone = ? OR fingerprint_hash = ? LIMIT 1");
|
||||
global $blindIndex;
|
||||
$emailBidx = $blindIndex ? $blindIndex->index('users.email', $email) : null;
|
||||
$phoneBidx = $blindIndex ? $blindIndex->index('users.phone', $phone) : null;
|
||||
|
||||
// كشف التكرار عبر الفهرس أيضاً: بدونه يُقبل نفس البريد مرتين تحت التشفير
|
||||
// العشوائي لأن النصين المشفّرين لن يتطابقا.
|
||||
$check = $con->prepare(
|
||||
"SELECT id FROM users
|
||||
WHERE email = ? OR phone = ? OR fingerprint_hash = ?
|
||||
OR (? IS NOT NULL AND email_bidx = ?)
|
||||
OR (? IS NOT NULL AND phone_bidx = ?)
|
||||
LIMIT 1"
|
||||
);
|
||||
|
||||
// تشفير الحقول للبحث عنها إذا كانت مشفرة في قاعدة البيانات (حسب تصميم النظام)
|
||||
$encEmail = $encryptionHelper->encryptData($email);
|
||||
// ملاحظة: البحث بالهاتف والبريد المشفر يتطلب مطابقة دقيقة أو البحث بالـ Hash إذا كان متوفراً
|
||||
// هنا سنفترض البحث بالبيانات الممرة مباشرة أو المشفرة حسب ما تقتضيه سياسة connect.php
|
||||
|
||||
$check->execute([$email, $phone, $fpHash]);
|
||||
$check->execute([$email, $phone, $fpHash, $emailBidx, $emailBidx, $phoneBidx, $phoneBidx]);
|
||||
|
||||
if ($check->rowCount() > 0) {
|
||||
jsonError("هذا الحساب أو الجهاز مسجل مسبقاً.");
|
||||
@@ -61,8 +73,8 @@ try {
|
||||
$encFp = $encryptionHelper->encryptData($fingerprint);
|
||||
|
||||
// 3. الإدخال في قاعدة البيانات (الحالة الافتراضية هي 0 أو pending)
|
||||
$sql = "INSERT INTO users (id, first_name, last_name, email, phone, password, fingerprint, fingerprint_hash, user_type, created_at)
|
||||
VALUES (:id, :fname, :lname, :email, :phone, :pass, :fp, :fp_hash, 'service', NOW())";
|
||||
$sql = "INSERT INTO users (id, first_name, last_name, email, phone, password, fingerprint, fingerprint_hash, user_type, created_at, email_bidx, phone_bidx)
|
||||
VALUES (:id, :fname, :lname, :email, :phone, :pass, :fp, :fp_hash, 'service', NOW(), :email_bidx, :phone_bidx)";
|
||||
|
||||
|
||||
$stmt = $con->prepare($sql);
|
||||
@@ -74,7 +86,9 @@ try {
|
||||
':phone' => $encPhone,
|
||||
':pass' => $hashedPassword,
|
||||
':fp' => $encFp,
|
||||
':fp_hash' => $fpHash
|
||||
':fp_hash' => $fpHash,
|
||||
':email_bidx' => $emailBidx,
|
||||
':phone_bidx' => $phoneBidx
|
||||
]);
|
||||
|
||||
printSuccess([
|
||||
|
||||
Reference in New Issue
Block a user