DISABLE_WP_CRON = true schließt den wp-cron.php-Endpunkt nicht ab; es verhindert lediglich, dass WordPress seine eigene Loopback-Anfrage ausführt. Die Datei bleibt über das Web erreichbar, sodass jeder sie weiterhin aufrufen und einen vollständigen WordPress-Bootstrap erzwingen kann.
Dieser versteckte Einstiegspunkt kann CPU, Arbeitsspeicher und PHP-Worker verschwenden, besonders auf hochfrequentierten Seiten. Wenn Sie dachten, Sie hätten die Tür zugemacht, haben Sie es noch nicht – zumindest noch nicht.
Warum die Einstellung oft missverstanden wird
Wenn WordPress eine geplante Aufgabe ausführt, versucht es zuerst eine schnelle HTTP-Anfrage an seine eigene wp-cron.php-Datei. Das Setzen von DISABLE_WP_CRON auf true weist den Core an, diese interne Anfrage zu überspringen. Der Core ändert nicht die Webserver-Konfiguration und fügt auch keine Authentifizierungsebene für wp-cron.php hinzu. Das Skript bleibt eine öffentliche URL, die einen 200-Status zurückgibt, selbst wenn der PHP-Prozess vorzeitig abbricht.
Ein Angreifer, der die URL entdeckt, kann sie wiederholt aufrufen (pingen), wodurch WordPress jedes Mal alle Plugins, Themes und die Datenbank laden muss. Auf einem Shared-Host oder einer Website mit begrenzten PHP-Workern kann dieser einzelne Endpunkt zu einem Denial-of-Service-Vektor werden.
Was wirklich zu tun ist
Um geplante Aufgaben an einen Scheduler auf Systemebene (cron, systemd-timer usw.) zu verlagern und die öffentliche Tür zu schließen, folgen Sie diesen fünf Schritten.
1. Den internen Loopback deaktivieren
Fügen Sie die Zeile
define( 'DISABLE_WP_CRON', true );
zu wp-config.php hinzu. Dies verhindert, dass WordPress seine eigene HTTP-Anfrage stellt, stoppt aber nicht externe Aufrufe.
2. wp-cron.php auf Webserver-Ebene blockieren
Fügen Sie bei Nginx beispielsweise einen location-Block ein, der 403 Forbidden zurückgibt:
location = /wp-cron.php {
return 403;
}
Der Server lehnt die Anfrage nun ab, noch bevor PHP überhaupt startet, wodurch die Bootstrap-Kosten entfallen.
3. Ein mu-Plugin als Sicherheitsnetz hinzufügen
Erstellen Sie ein Must-Use-Plugin (platziert in wp-content/mu-plugins), das jede Anfrage an wp-cron.php protokolliert und mit einem 403 beendet. Dies fängt Anfragen ab, die die Serverregel irgendwie umgehen – etwa durch einen anderen Hostnamen oder eine CDN-Edge-Regel.
4. Action Scheduler Async-Aufrufe unterdrücken
Viele Plugins verwenden die Action Scheduler Library, die eigene Loopback-Anfragen auslösen kann. Nutzen Sie den Hook action_scheduler_queue_runner und brechen Sie frühzeitig für Anfragen ab, die nicht über die CLI laufen, um zu verhindern, dass die Library versucht, ihre eigenen Türen zu öffnen.
5. Den Queue Runner vom WP-Cron-Hook trennen
Entfernen Sie den standardmäßigen Action Scheduler Queue Runner, der an den wp-Cron-Hook gebunden ist. Dies stellt sicher, dass die Warteschlange nur dann läuft, wenn Sie sie explizit über die Befehlszeile aufrufen.
Jobs auf die richtige Weise ausführen
Sobald der öffentliche Endpunkt versiegelt ist, nutzen Sie den System-Scheduler, um WordPress einmal pro Minute (oder in der gewünschten Frequenz) via WP-CLI aufzurufen:
wp cron event run --due-now
Dieser einzelne Befehl verarbeitet sowohl die Core-Cron-Events als auch die Action Scheduler Warteschlange in einer kontrollierten Umgebung unter Verwendung desselben PHP-Prozesses, den Sie auch für jede andere CLI-Aufgabe verwenden würden.
Messbare Vorteile
- Sicherheit – Kein nicht authentifizierter Benutzer kann schwere Hintergrundarbeiten starten.
- Performance – PHP-Worker bleiben für echte Besucher verfügbar; Speicher-Spitzen durch zufällige Cron-Aufrufe verschwinden.
- Zuverlässigkeit – Die Zeitplanung wird proaktiv; Sie wissen genau, wann ein Job läuft, da er vom System-Cron gesteuert wird und nicht durch den Seitenaufruf eines Besuchers.
Worauf Sie nach der Änderung achten sollten
Verlassen Sie sich nicht auf den HTTP-Statuscode von wp-cron.php; dieser kann immer noch 200 zurückgeben, selbst wenn er durch PHP blockiert wird. Achten Sie stattdessen auf:
- Überwachen Sie die Größe der Action Scheduler Warteschlange. Eine wachsende Warteschlange deutet oft auf verpasste Durchläufe hin.
- Prüfen Sie die Server-Logs auf „403“-Einträge im
wp-cron.phpLocation-Block. - Beobachten Sie die PHP-FPM- oder FastCGI-Prozessanzahl während der Spitzenzeiten, um zu bestätigen, dass die Last gesunken ist.
Ein Hinweis zur Vorsicht
Einige Administratoren lassen DISABLE_WP_CRON auf false, weil sie darauf vertrauen, dass Websites mit wenig Traffic den Cron von Natur aus auslösen. Der oben beschriebene Ansatz entfernt diese Abhängigkeit vollständig, fügt aber einen Wartungsschritt hinzu: Sie müssen sicherstellen, dass der System-Scheduler zuverlässig läuft. Wenn der Cron-Daemon des Servers ausfällt, stoppen die geplanten Aufgaben. Kombinieren Sie das Setup mit einer Überwachung des System-Cron-Dienstes, um diese Falle zu vermeiden.
Fazit: Das Setzen von DISABLE_WP_CRON auf true stoppt nur das Selbst-Pingen von WordPress; es schließt den öffentlichen wp-cron.php-Endpunkt nicht. Blockieren Sie die Datei auf Webserver-Ebene, fügen Sie ein mu-Plugin als Fallback hinzu und leiten Sie alle geplanten Aufgaben über einen System-Scheduler via WP-CLI um. Dies sichert die Website, reduziert unnötige PHP-Arbeit und gibt Ihnen die präzise Kontrolle darüber, wann Hintergrundaufgaben ausgeführt werden.
