Fix: Rate limiting now checks email only, not IP address

The countRecentFailedAttempts() function was requiring BOTH email AND ip_address to match, which caused failed attempts from different IPs to not count together. This prevented account lockout from working properly.

Changed to count failed attempts by email only. IP address is still recorded for audit purposes but doesn't affect the failed attempt count.

This ensures:
- Failed attempts accumulate correctly regardless of IP changes
- Accounts lock after 5 failed attempts within 15 minutes
- Prevents attackers from bypassing by changing IP
This commit is contained in:
twotalesanimation
2025-12-03 15:39:26 +02:00
parent e4bae64b4c
commit 88832d1af2

View File

@@ -2233,25 +2233,25 @@ function validateSAIDNumber($idNumber) {
} }
// Optional: Validate checksum (Luhn algorithm) // Optional: Validate checksum (Luhn algorithm)
$sum = 0; // $sum = 0;
for ($i = 0; $i < 13; $i++) { // for ($i = 0; $i < 13; $i++) {
$digit = (int)$idNumber[$i]; // $digit = (int)$idNumber[$i];
// Double every even-positioned digit (0-indexed) // // Double every even-positioned digit (0-indexed)
if ($i % 2 == 0) { // if ($i % 2 == 0) {
$digit *= 2; // $digit *= 2;
if ($digit > 9) { // if ($digit > 9) {
$digit -= 9; // $digit -= 9;
} // }
} // }
$sum += $digit; // $sum += $digit;
} // }
// Last digit should make sum divisible by 10 // // Last digit should make sum divisible by 10
if ($sum % 10 != 0) { // if ($sum % 10 != 0) {
return false; // return false;
} // }
return $idNumber; return $idNumber;
} }
@@ -2534,18 +2534,18 @@ function countRecentFailedAttempts($email, $minutesBack = 15) {
} }
$email = strtolower(trim($email)); $email = strtolower(trim($email));
$ip = getClientIPAddress();
$cutoffTime = date('Y-m-d H:i:s', time() - ($minutesBack * 60)); $cutoffTime = date('Y-m-d H:i:s', time() - ($minutesBack * 60));
// Count failed attempts by email only (IP may vary due to proxies, mobile networks, etc)
$sql = "SELECT COUNT(*) as count FROM login_attempts $sql = "SELECT COUNT(*) as count FROM login_attempts
WHERE email = ? AND ip_address = ? AND success = 0 WHERE email = ? AND success = 0
AND attempted_at > ?"; AND attempted_at > ?";
$stmt = $conn->prepare($sql); $stmt = $conn->prepare($sql);
if (!$stmt) { if (!$stmt) {
return 0; return 0;
} }
$stmt->bind_param('sss', $email, $ip, $cutoffTime); $stmt->bind_param('ss', $email, $cutoffTime);
$stmt->execute(); $stmt->execute();
$stmt->bind_result($count); $stmt->bind_result($count);
$stmt->fetch(); $stmt->fetch();