From def849ac11a4bd322ba8a09dd5b17c0cac82fe1c Mon Sep 17 00:00:00 2001 From: twotalesanimation <80506065+twotalesanimation@users.noreply.github.com> Date: Wed, 3 Dec 2025 15:43:39 +0200 Subject: [PATCH] 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. --- functions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions.php b/functions.php index 3fa706d7..6e12222c 100644 --- a/functions.php +++ b/functions.php @@ -2534,18 +2534,18 @@ function countRecentFailedAttempts($email, $minutesBack = 15) { } $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) + // Using DATE_SUB to ensure proper datetime comparison $sql = "SELECT COUNT(*) as count FROM login_attempts WHERE email = ? AND success = 0 - AND attempted_at > ?"; + AND attempted_at > DATE_SUB(NOW(), INTERVAL ? MINUTE)"; $stmt = $conn->prepare($sql); if (!$stmt) { return 0; } - $stmt->bind_param('ss', $email, $cutoffTime); + $stmt->bind_param('si', $email, $minutesBack); $stmt->execute(); $stmt->bind_result($count); $stmt->fetch();