Implementierung von Ratenbegrenzung und IP-Blockierung in Willow CMS

Dieser Blogbeitrag beschreibt ausführlich die Implementierung von Ratenbegrenzung und IP-Blockierung in einem Willow CMS und konzentriert sich dabei auf die wichtigsten Codekomponenten und deren Gründe. Diese Informationen richten sich an Entwickler, die ähnliche Sicherheitsmaßnahmen in ihren Projekten implementieren möchten. Seit Willow für diese Site live geschaltet wurde, war es interessant, die Protokolle anzusehen und all die Versuche aus Singapur zu sehen, Exploits zu finden!

Ratenbegrenzung

Ratenbegrenzung ist eine Technik zum Schutz von Anwendungsressourcen durch Beschränkung der Anzahl von Anfragen, die ein Client innerhalb eines bestimmten Zeitraums stellen kann. Diese Implementierung verwendet aus Effizienzgründen das Middleware-Muster und den Caching-Mechanismus von CakePHP.

RateLimitMiddleware

Der Kern der Ratenbegrenzungslogik befindet sich in src/Middleware/RateLimitMiddleware.php . Lesen Sie den vollständigen Code auf GitHub. Hier ist eine Aufschlüsselung der wichtigsten Teile:


class RateLimitMiddleware implements MiddlewareInterface
{
    // Use default configuration or that provided to the constructor
    public function __construct(array $config = [])
    {
        $this->limit = $config['limit'] ?? 3;
        $this->period = $config['period'] ?? 60;
        // Specific some default routes that should be rate limited
        $this->rateLimitedRoutes = $config['routes'] ?? [
            '/users/login',
            '/users/register',
            '/articles/add-comment/',
        ];
    }

    // Process a server request and return a response.
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // Use CakePHP method to get the client IP (more on this later)
        $ip = $request->clientIp();
        $route = $request->getUri()->getPath();

        if ($this->isRouteLimited($route)) {
            $key = "rate_limit_{$ip}_normal";
            $rateData = $this->updateRateLimit($key, $this->period);

            if ($rateData['count'] > $this->limit) {
                // ...
                throw new TooManyRequestsException(
                    // ...
                );
            }
        }

        return $handler->handle($request);
    }

    // ... more methods below, see the full file on GitHub
}

Wichtige Aspekte dieser Middleware:

  • Zielrouten: DieisRouteLimited() Die Methode prüft, ob die aktuelle Route einer Geschwindigkeitsbegrenzung unterliegt, und ermöglicht so eine detaillierte Kontrolle.
  • Caching für Effizienz:updateRateLimit() Die Methode liest und erhöht die Anzahl der Anfragen aus dem Cache. Dadurch werden bei jeder Anfrage Datenbankabfragen vermieden und die Leistung verbessert. Wenn der Zeitraum abgelaufen ist, wird der Zähler zurückgesetzt.
  • Ausnahmebehandlung: Wenn das Limit überschritten wird,TooManyRequestsException wird ausgelöst, die Ausführung wird angehalten und ein 404-Fehler an den Client gesendet, einschließlich derRetry-After Kopfzeile.
  • Protokollierung: Verstöße werden zur Analyse und Überwachung protokolliert.
  • Konfiguration: Die Anzahl der zulässigen Anfragen und die Zeiträume werden aus Einstellungswerten abgerufen, sodass Sie diese im Admin-Bereich konfigurieren können.
  • Wildcard-Unterstützung: Die Reihe der geschwindigkeitsbegrenzten Routen unterstützt Wildcards, sodass Siepages/* oderarticles/* . Siehe die Methode isRouteLimited() .

IP-Blockierung

Die IP-Blockierung fügt eine weitere Sicherheitsebene hinzu, indem sie Anfragen von bekannten böswilligen IP-Adressen verhindert. Die Implementierung kombiniert Caching mit Datenbanksuche und verwaltet so die Liste blockierter IPs effizient.

IpBlockerMiddleware

Diese Middleware src/Middleware/IpBlockerMiddleware.php kümmert sich um das Blockieren und Verfolgen verdächtiger Aktivitäten. Den vollständigen Code finden Sie auf GitHub. Hier ist eine Aufschlüsselung der wichtigsten Teile:

class IpBlockerMiddleware implements MiddlewareInterface
{

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // ...

        $clientIp = $request->clientIp();

        if ($this->ipSecurity->isIpBlocked($clientIp)) {
            // Return 403 Forbidden
        }

        if ($this->ipSecurity->isSuspiciousRequest($route, $query)) {
            // Log suspicious activity
            $this->ipSecurity->trackSuspiciousActivity($clientIp, $route, $query);

            // Return 403 Forbidden
        }

        return $handler->handle($request);
    }
}

Und so funktioniert es:

  • IP-Blockierung: Wenn die anfragende IP in der Sperrliste steht (überprüft überisIpBlocked() ), wird sofort eine 403-Forbidden-Antwort zurückgegeben.
  • Erkennung verdächtiger Anfragen: DieisSuspiciousRequest() Die Methode prüft anhand einer Liste verdächtiger URL-Muster. Wenn eine Übereinstimmung gefunden wird, wird die Aktivität protokolliert und verfolgt.

IpSecurityService

Die Datei src/Service/IpSecurityService.php verwaltet die Kernlogik für die IP-Blockierung und die Erkennung verdächtiger Aktivitäten. Sie verwendet Caching zur Leistungssteigerung und bietet einen zentralen Ort für IP-bezogene Funktionen. Lesen Sie den vollständigen Code auf GitHub. Hier ist eine Aufschlüsselung der wichtigsten Teile:

class IpSecurityService
{
    private array $suspiciousPatterns = [/* list of regular expressions */ ];

    public function isIpBlocked(string $ip): bool
    {
        // Caching logic ...

        // Database lookup if not in cache
        $blockedIp = $blockedIpsTable->find()
            // ... expiry checks ...
            ->first();

        // ... caching logic

        return $blockedStatus;
    }


    public function blockIp(string $ip, string $reason, ?DateTime $expiresAt = null): bool
    {
        // ... database save to blocked_ips table and logging the event
    }


    public function isSuspiciousRequest(string $route, string $query): bool
    {
        // Regex matching against suspicious patterns
        // ... logging ...
    }

    public function trackSuspiciousActivity(string $ip, string $route, string $query): void
    {
        // Increase suspicious activity counter using cache
        // ... progressive blocking logic (if IP has offended in last 24 hours block for 48 hours) ...
    }
}

Wichtige Verbesserungen und Funktionen dieses Dienstes:

  • Caching: BeideisIpBlocked() UndtrackSuspiciousActivity() Verwenden Sie Caching, um die Datenbanklast zu reduzieren.
  • Progressive Blockierung: DietrackSuspiciousActivity() Methode implementiert progressive Sperrung. Wiederholungstäter werden länger gesperrt.
  • Umfassende Musterliste: Eine detaillierte Liste verdächtiger Muster in$suspiciousPatterns hilft, eine Vielzahl bösartiger Anfragen zu erkennen. Ich denke, in Zukunft werde ich diese aus der Datenbank laden/zwischenspeichern, um das Bearbeiten/Hinzufügen neuer Regeln zu vereinfachen.

Load Balancer-Unterstützung

Der Code unterstützt Willow CMS, das hinter einem Load Balancer läuft, indem er Proxy-Headern vertraut. Dies wird durch die Einstellung aktiviert'Security.trustProxy' Zutrue auf der Seite Willow CMS Admin->Einstellungen. Dadurch wird sichergestellt, dass die Client-IP und andere Anforderungsinformationen korrekt aus den weitergeleiteten Headern abgerufen werden und wir den integrierten CakePHP-Framework-Code verwenden, um die Client-IP zuverlässig abzurufen.

if (SettingsManager::read('Security.trustProxy', false)) {
            $request = $request->withAttribute('trustProxy', true);
        }

PHPUnit Tests

Dies ist ziemlich wichtiger Code, daher muss er mit einigen Unit-Tests versehen werden. Sie können sie in RateLimitMiddlewareTest und IpBlockerMiddlewareTest nachlesen. Ich verwende Datenprovider in PHPUnit, um die Tests sauber und leicht aktualisierbar zu halten.

IpBlockerMiddlewareTest

Dieser Testfall konzentriert sich auf dieIpBlockerMiddleware , deckt Fälle von blockierten IPs, zwischengespeicherten Status, abgelaufenen Blockierungen, verdächtigen Anfragen und Pfaddurchquerungen ab.

RateLimitMiddlewareTest

Diese Testsuite zieltRateLimitMiddleware , mit Schwerpunkt auf Ratenbegrenzungslogik, Platzhalterrouten und unterschiedlicher Routenbehandlung.

  • Setup: DiesetUp Methode löscht den 'rate_limit'-Cache vor jedem Test und stellt so eine saubere Grundlage für eine genaue Ratenzählung sicher. Sie definiert auch Ratenbegrenzungsparameter (limit Undperiod ) für die Tests.
  • Testfälle:

Diese Testfälle demonstrieren bewährte Vorgehensweisen zum Testen von Middleware. Sie bieten zielgerichtete Szenarien, nutzen Mocking, wo es angebracht ist, und verwenden Datenanbieter zum effizienten Testen mehrerer Varianten.

Schlagwörter

Middleware PHPUnit Entwicklung KuchenPHP Sicherheit