fix(security): fix login AND logic to OR, add signup input validation, separate OTP rate limit keys

This commit is contained in:
Hamza-Ayed
2026-06-17 07:05:58 +03:00
parent 70c06edd71
commit 1a9619f9f8
3 changed files with 38 additions and 7 deletions

View File

@@ -6,8 +6,23 @@ $email = filterRequest('email');
$phone = filterRequest('phone'); $phone = filterRequest('phone');
$password = filterRequest('password'); $password = filterRequest('password');
// Hash the password if (empty($phone) && empty($email)) {
$hashed_password = password_hash($password, PASSWORD_DEFAULT); echo json_encode(["status" => "Failure", "data" => "Phone or email is required."]);
exit;
}
// Build WHERE dynamically: support phone-only, email-only, or both
$conditions = [];
$params = [':password' => $password];
if (!empty($phone)) {
$conditions[] = "passengers.phone = :phone";
$params[':phone'] = $phone;
}
if (!empty($email)) {
$conditions[] = "passengers.email = :email";
$params[':email'] = $email;
}
$where = implode(' OR ', $conditions);
$sql = "SELECT $sql = "SELECT
passengers.`id`, passengers.`id`,
@@ -29,11 +44,9 @@ FROM
`passengers` `passengers`
LEFT JOIN email_verifications ON email_verifications.email = passengers.email LEFT JOIN email_verifications ON email_verifications.email = passengers.email
WHERE WHERE
passengers.phone = :phone AND passengers.email = :email "; $where";
$stmt = $con->prepare($sql); $stmt = $con->prepare($sql);
$stmt->bindParam(':email', $email); $stmt->execute($params);
$stmt->bindParam(':phone', $phone);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC); $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
$count = $stmt->rowCount(); $count = $stmt->rowCount();

View File

@@ -7,7 +7,7 @@ require_once __DIR__ . '/../../functions.php';
// 0. Rate Limiting: 3 محاولات OTP كل 5 دقائق لكل IP // 0. Rate Limiting: 3 محاولات OTP كل 5 دقائق لكل IP
$rateLimiter = new RateLimiter($redis); $rateLimiter = new RateLimiter($redis);
$rateLimiter->enforce(RateLimiter::identifier(), 'otp'); $rateLimiter->enforce(RateLimiter::identifier(), 'otp_verify');
// 1. Fetch input parameters // 1. Fetch input parameters
$phone_number = filterRequest("phone_number"); $phone_number = filterRequest("phone_number");

View File

@@ -12,6 +12,24 @@ $gender = filterRequest("gender");
$birthdate = filterRequest("birthdate"); $birthdate = filterRequest("birthdate");
$site = filterRequest("site"); $site = filterRequest("site");
// --- Input Validation ---
if (empty($phone) || strlen(preg_replace('/\D+/', '', $phone)) < 8) {
jsonError("Valid phone number is required.");
exit;
}
if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
jsonError("Valid email address is required.");
exit;
}
if (empty($password) || strlen($password) < 6) {
jsonError("Password must be at least 6 characters.");
exit;
}
if (empty($first_name) || empty($last_name)) {
jsonError("First name and last name are required.");
exit;
}
// تشفير البيانات الحساسة // تشفير البيانات الحساسة
$phone = $encryptionHelper->encryptData($phone); $phone = $encryptionHelper->encryptData($phone);
$email = $encryptionHelper->encryptData($email); $email = $encryptionHelper->encryptData($email);