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:
twotalesanimation
2025-12-03 15:43:39 +02:00
parent 88832d1af2
commit def849ac11

View File

@@ -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();