Fix: Use SQL DATE_SUB for accurate datetime comparison in rate limiting
Changed countRecentFailedAttempts() to use MySQL DATE_SUB(NOW(), INTERVAL ? MINUTE) instead of PHP-calculated cutoff time. This ensures consistent datetime comparison on the database server without timezone mismatches between PHP and MySQL. This fixes the issue where the AND attempted_at condition was filtering out all recent attempts due to timestamp comparison inconsistencies.
This commit is contained in:
@@ -2534,18 +2534,18 @@ function countRecentFailedAttempts($email, $minutesBack = 15) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$email = strtolower(trim($email));
|
$email = strtolower(trim($email));
|
||||||
$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)
|
// Count failed attempts by email only (IP may vary due to proxies, mobile networks, etc)
|
||||||
|
// Using DATE_SUB to ensure proper datetime comparison
|
||||||
$sql = "SELECT COUNT(*) as count FROM login_attempts
|
$sql = "SELECT COUNT(*) as count FROM login_attempts
|
||||||
WHERE email = ? AND success = 0
|
WHERE email = ? AND success = 0
|
||||||
AND attempted_at > ?";
|
AND attempted_at > DATE_SUB(NOW(), INTERVAL ? MINUTE)";
|
||||||
$stmt = $conn->prepare($sql);
|
$stmt = $conn->prepare($sql);
|
||||||
if (!$stmt) {
|
if (!$stmt) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt->bind_param('ss', $email, $cutoffTime);
|
$stmt->bind_param('si', $email, $minutesBack);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$stmt->bind_result($count);
|
$stmt->bind_result($count);
|
||||||
$stmt->fetch();
|
$stmt->fetch();
|
||||||
|
|||||||
Reference in New Issue
Block a user