WordPress utf8mb4, der Emoji-Trojaner & BackupBuddy

Wo soll ich anfangen: Bei den vergeblichen Versuchen, meine lokale Entwicklungsseite per BackupBuddy auf den Remote-Server zu übertragen? Beim Ärger über den forcierten Wechsel der Datenbank-Kollation auf utf8mb4? Bei der Erkenntnis, dass ein „Emoji-Tojaner“ der ganzen Sache zugrunde liegt? Vielleicht am Besten da wo es auch für mich losging…

Lokales WordPress-Development

Ich bin großer Fan des WordPress-Frameworks Sage (zuvor hieß das Theme auch mal ‚Roots‘). Beim Setup des Themes gab es bei meinem Server-Hoster Uberspace kurioserweise ein paar Probleme – obwohl man dort ohne Weiteres auf die Shell zugreifen und Node.js / npm nutzen kann. Nach einigem hin und her mit dem (hervorragenden) Support beschloss ich also, mich wieder aufs lokale Entwicklen zu verlegen, was ja auch ohne Frage etliche Vorteile mit sich bringt (siehe z.B. BrowserSync).

Leider kam dieser Workflow-Wandel zu einem hohen Preis und daran hat WordPress selbst einen großen Anteil. Aber der Reihe nach…

MAMP Pro & die MySQL-Versionierung

Fix MAMP Pro aufgesetzt, die nötigen dependancies für npm, gulp & Co. auf dem Mac installiert und fortan glückselig lokal programmiert. Denkste. Mit dem ersten „Push“ der Entwicklungsseite hin zum Remote-Server (ich verwende dafür das Migrations-Tool von BackupBuddy) kam dann die Ernüchterung: Eine falsche MySQL-Kollation soll für den Fehler verantwortlich sein? Seit wann gibt es das denn bitte?

WordPress 4.2.x und utf8mb4

Konkret seit dem 02.04.2015, also dem Tag an dem WordPress 4.2 ausgeliefert wurde. Im WordPress Core-Blog wird darüber ausführlich berichtet, Kurzversion:

Bei allen MySQL-Versionen ab 5.5.3 wird WordPress automatisch mit utf8mb4 statt bisher utf8 eingerichtet. Davon bekommt der User im Idealfall gar nichts mit und es ist faktisch auch kein großer Unterschied (würde man zumindest denken), es wird aber dann problematisch, wenn man unterschiedliche MySQL-Versionen auf seinen Servern verwendet und nun seine Seite verschieben will… Im lokalen MAMP-Setup findet standardmäßig die neuste MySQL-Variante Verwendung, ergo wurde meine neue Seite bzw. die zugehörige Datenbank als utf8mb4 angelegt.

Da Uberspace MySQL in der Version 5.1.x vorhält war mir dann recht schnell klar, woran es liegt: Fehlende Abwärts-Kompatibilität. Die neue Kollation wird nicht supported und es gibt (noch) kein Migrationsskript, das darauf reagieren würde. Fazit: Komische Fehlercodes und fehlgeschlagene Migration.

BackupBuddy-Error UTF8MB4

Resonanz in der WP-Szene & Hoster-Problematik

Wie man sich vorstellen kann wurde nicht nur ich von diesem forcierten Wandel kalt erwischt. Im Netz allgemein und im WordPress Support-Forum im Besonderen wird das Thema auseinandergenommen. Die WP-Entwickler beharren dabei auf dem recht radikalen Standpunkt, solche Weiterentwicklungen müssen halt auch ein wenig „forciert“ werden, auch wenn der User an sich wenig Einfluss auf die Versionierungs-Politik des Hosters nehmen kann. Man könnte auch sagen, es sei absolut illusorisch, dass ein Hoster sich mit einem Mal für ein solch gravierendes Upgrade entscheidet – hier darf ich meinen Hoster Uberspace zitieren:

Dagegen spricht in erster Linie, dass wir uns damit von den Updates die unsere Linux-Distribution bereitstellt abschneiden würden und dass ein solches Upgrade eine unvorhersehbar große Zahl von breits vorhandenen Setups unserer User schlicht brechen würde, d.h. unvorhersehbar viele Webapplikationen würden dabei ganz oder teilweise kaputt gehen. Wenn dann könnten wir höchstens neben der bereits vorhandenen MySQL-Version eine zweite, neuere bereitstellen, womit wir hier aber immer noch von Updates abgeschnitten wären und die Updates alle selber machen müssten. Außerdem würde uns das erheblichen Mehraufwand bei den MySQL-Backups bereiten.

Da beißt sich die Schlange eben in den eigenen Schwanz: Der User startet und entwickelt auf einer älteren (MySQL- / PHP- / whatever-)Version was dazu führt, dass man nicht einfach ein (MySQL-)Update durchführen kann, weil ja auf älteren Versionen basierende Anwendungen dann kaputt gehen könnten. Hmm.

Nur um das klarzustellen: Ich habe volles Verständnis für den konservativeren, abwärts-kompatiblen Ansatz und kann mir nur zu gut vorstellen, was es vor allem für kleinere Hoster bedeutet, mehrere Versionen der Anwendungen bereitzustellen. Insofern war mein erster Impuls, dass WordPress einen solchen Switch nicht einfach so (= ohne Warnung oder gar Auswahlmöglichkeit seitens des Users) durchführen darf. Warum machen die das also?

Der Emoji-Trojaner

Nach einigem Wühlen bin ich auf einen Artikel bei Post Status gestoßen, der eine recht einfache Erklärung für den resoluten Schritt liefert: Hier wird eine Sicherheitslücke gestopft. Im Zuge des neuen Emoji-Features ließ sich der Fix dann recht gut „en passant“ verkaufen… Das erklärt auf jeden Fall die konsequente Ablehnung für jegliche Abwärts-Kompatibilität (falls denn eine neue MySQL-Version vorhanden ist).

Manueller Fix für utf8mb4

WICHTIG: Bitte vorher ein Backup anlegen! Unter Umständen wird die Seite durch den „Fix“ auch zerhackt… Das liegt vor Allem daran, ob Ihr irgendwelche Inhalte habt, die utf8mb4 nutzen und auch nur mit dieser Kollation funktionieren.

Aber was tun jetzt? Ben Lobaugh hält in seinem Blog eine zwar nicht elegante aber doch praktikable Lösung parat: Ein Shell-Skript mit dem man die Kollation seiner MySQL-Datenbank nachträglich von utf8mb4 auf utf8 abändern kann:

DB="your_database_name"
USER="your_db_user"
PASS="your_db_pass"
(
    echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;'
    mysql -p$PASS -u $USER "$DB" -e "SHOW TABLES" --batch --skip-column-names \
    | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;'
) \
| mysql -p$PASS -u $USER "$DB"

Das Skript dann einfach auf den Desktop (oder wo auch immer) legen, per Terminal dorthin navigieren und einmalig ausführen.

cd Users/XYZ/Desktop
sh utf8.sh

Jetzt muss nur noch in der wp-config.php der Kollations-Eintrag entsprechend geändert werden:

define('DB_CHARSET', 'utf8');

Entsprechend sollte die Seite jetzt wieder auf UTF8 statt UTF8MB4 gesetzt sein und sich z.B. per BackupBuddy problemlos auch auf einen Server mit niedrigerer MySQL-Version migrieren lassen.

Bildquelle Headerbild: https://en.blog.wordpress.com/2014/11/06/emoji-everywhere