Die aktuelle Version des bekannten Caching-Plugins WP Rocket V3.23.2.1 führt zu einem Crash beim Update auf WordPress 7.1. Besucher der Webseite sehen dann nur:
Übeltäter ist das Cloudflare-Plugin von WP Rocket.
Dieses findet sich unter:
/wp-content/plugins/wp-rocket/inc/ThirdParty/Plugins/CDN/Cloudflare.php
WP Rocket versucht in seiner Cloudflare-Kompatibilitätsschicht, bestimmte Hooks des offiziellen Cloudflare-Plugins wieder abzumelden. Dazu läuft es durch die registrierten WordPress-Callbacks und prüft anhand des Array-Keys, ob dieser auf einen bestimmten Methodennamen endet.
Vereinfacht macht WP Rocket dabei so etwas:
foreach ( $original_wp_filter[ $priority ] as $key => $config ) {
if ( substr( $key, - strlen( $method ) ) !== $method ) {
continue;
}
}
Das Problem: WP Rocket geht hier davon aus, dass $key mmer ein String ist. Genau das ist bei WordPress-Hooks aber nicht garantiert.Das Callback-Array enthält mindestens einen numerischen Key, also einen Integer. Dann passiert effektiv:
substr( 123, -10 );
Unter aktuellem PHP ist das kein harmloser Sonderfall mehr, sondern führt zu einem TypeError:
substr(): Argument #1 ($string) must be of type string, int given
Da diese Prüfung während des WordPress-init-Hooks ausgeführt wird, entsteht der Fehler sehr früh im Request. Deshalb betrifft er nicht nur einzelne Funktionen von WP Rocket, sondern kann die komplette Seite inklusive /wp-login.php mit einem Fatal Error lahmlegen.
In der betroffenen Datei hängt WP Rocket seine Methode selbst an init und ruft dort zwei Bereinigungen für Cloudflare-Callbacks auf. Die eigentliche problematische Stelle ist das ungeprüfte substr() auf dem Callback-Key.
Der Fix besteht deshalb schlicht darin, vor dem substr() sicherzustellen, dass $key wirklich ein String ist:
if ( ! is_string( $key ) ) {
continue;
}
Einfacher Fix
Um die Seite auch weiterhin (bis zum offiziellen Update) mit WP Rocket nutzen zu können, ändert man diese Datei ab (per FTP/SSH/SFTP-Zugriff auf dem Hostingpaket):
/wp-content/plugins/wp-rocket/inc/ThirdParty/Plugins/CDN/Cloudflare.php
@@ -557,6 +557,10 @@ protected function unregister_callback( string $hook, string $method, int $priority = 10 ) {
foreach ( $original_wp_filter[ $priority ] as $key => $config ) {
+ if ( ! is_string( $key ) ) {
+ continue;
+ }
+
if ( substr( $key, - strlen( $method ) ) !== $method ) {
continue;
}




