add admin cookie check
This commit is contained in:
68
classes/rules/RateLimitRule.php
Normal file
68
classes/rules/RateLimitRule.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
|
||||
class RateLimitRule implements RuleInterface
|
||||
{
|
||||
const MAX_404_REQUESTS = 20; // Allow a maximum of 20 dead links...
|
||||
const TIME_WINDOW = 300; // ...within 300 seconds (5 minutes)
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$ip = BotLogger::getRealIp();
|
||||
if (BotLogger::isWhitelisted($ip)) {
|
||||
return true;
|
||||
}
|
||||
$context = Context::getContext();
|
||||
|
||||
// 1. Instantly skip if this is NOT a 404 error page.
|
||||
// During the hookActionFrontControllerInitBefore hook, PrestaShop has already
|
||||
// resolved the route. If it failed, the controller is set to PageNotFoundController.
|
||||
if (!($context->controller instanceof PageNotFoundController)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 2. Safely check if the Cache module is installed and enabled
|
||||
if (!Module::isInstalled('dbmemorycache') || !Module::isEnabled('dbmemorycache')) {
|
||||
return true; // Pass gracefully if the module is missing or disabled
|
||||
}
|
||||
|
||||
/** @var DbMemoryCache $cache */
|
||||
$cache = Module::getInstanceByName('dbmemorycache');
|
||||
if (!$cache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. Generate a unique hash for this specific IP's 404 traffic
|
||||
$cacheKey = hash('sha256', '404_spam_limiter_' . $ip);
|
||||
|
||||
// 4. Lookup their current 404 hit count in the memory table
|
||||
$currentCount = 0;
|
||||
if ($cache->existsValue($cacheKey)) {
|
||||
$currentCount = (int) $cache->getValue($cacheKey);
|
||||
}
|
||||
|
||||
// 5. Increment their strike counter
|
||||
$currentCount++;
|
||||
|
||||
// 6. Have they triggered too many 404s?
|
||||
if ($currentCount > self::MAX_404_REQUESTS) {
|
||||
|
||||
// Log it so Fail2ban can block them at the server firewall level
|
||||
BotLogger::logBan($ip, '404_RATE_LIMIT_EXCEEDED');
|
||||
|
||||
// Drop the connection instantly to save server resources
|
||||
header('HTTP/1.1 429 Too Many Requests');
|
||||
die('429 Too Many Requests - Stop Scanning');
|
||||
}
|
||||
|
||||
// 7. Save the new strike count back to the cache
|
||||
// Note: Because we overwrite it here, this creates a "Sliding Window".
|
||||
// If a bot keeps spamming, the 300s timer resets every time, keeping them trapped!
|
||||
$cache->setValue($cacheKey, $currentCount, self::TIME_WINDOW);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user