WordPress ist das beliebteste Blog-CMS der Welt. Über 55% der 1 Million bekanntesten Webseiten (Alexa Ranking) benutzen WordPress als Content-Management-Software. Grund genug, sich bei der Installation ein wenig Gedanken über die Sicherheit zu machen.
Sicherheit und Flexibilität im Konflikt
Der Durchschnittsuser darf nicht das Gefühl haben, dass ihm die IT-Sicherheit in die Quere kommt. Hier gilt es den Spagat zwischen Sicherheit und Usability zu meistern. Das wissen auch die WordPress-Devs und lassen dem erfahrenen Blogger zugunsten der Usability noch ein wenig Freiraum für Verbesserungen im Sicherheitsbereich. Unbedingt notwendig sind diese Änderungen nicht, da WordPress selber als ziemlich sicher gilt und Updates schnell ausgerollt werden. Sinnvoll können sie allerdings trotzdem sein. Die folgenden Tipps gelten für alle WordPress-Versionen.
Die Rechteverteilung
Die Rechteverteilung spielt eine große Rolle. Das sollten nicht nur *nix-User wissen, sondern jeder, der sich ein wenig mit Systemadministration beschäftigt. Falsch vergebene Rechte können schnell Probleme hervorrufen und die Sicherheit extrem beeinflussen. Wichtig ist daher, dass sowohl die Files als auch die Ordner nicht auf das (für viele) wohlbekannte 777 (rwe-rwe-rwe) geCHMOD’ed werden. Es gilt: Die Dateien sollten 644er und die Ordner 755er Rechte besitzen. Über die Shell können wir dies ganz einfach über find für alle Ordner/Dateien im /wordpress_ordner erledigen.
find /wordpress_ordner -type f -exec chmod 644 {} \; find /wordpress_ordner -type d -exec chmod 755 {} \;
Die Userverwaltung
Dass WordPress nicht als root-User auf die Datenbank zugreifen und der dafür erstellte Benutzer nur die Rechte für die WP-DB besitzen sollte, muss ich wohl nicht erwähnen. Stattdessen möchte ich den Tipp geben, den user_login in der wp_options Tabelle zu ändern. Dieser wird zum Login in das WordPress-Backend verwendet. Da als Author bei den Artikeln der user_nicename angezeigt wird, können wir den user_login problemfrei ändern. Ratsam ist dies besonders, wenn man bislang einen Standardnamen wie ‘admin’ verwendet. Sollte dies der Fall sein, bräuchte ein potenzieller Angreifer nur noch das Passwort, welches ihr ggf. auch in anderen Anwendungen benutzt. Zum Ändern reicht das Ausführen eines SQL-Querys.
UPDATE wp_users SET user_login = 'caesar' WHERE user_login = 'admin';
Das Login-Interface
… ist wahrscheinlich das erste Ziel eines Angreifers. Grund genug, ein paar Vorkehrungen zu treffen. Bei einer normalen WP-Installation werden eine Menge an Informationen preisgegeben, sollte man sich ein wenig mit der wp-login.php beschäftigen. Bei Falscheingabe eines Usernamens wird die Information ausgegeben, dass der verwendete Username falsch sei (“Fehler: Falscher Benutzername.“). Versucht man es mit dem richtigen Username und einem falschen Passwort, erhalten wir die Ausgabe, dass das Passwort für den Usernamen falsch sei (“Das Passwort welches du für den Benutzernamen test eingegeben hast, ist falsch.“). Damit kann ein Angreifer z.B. durch simples Ausprobieren mehr oder weniger den richtigen Login-Namen für den User herausfinden, um sich mit evtl. woanders entwendeten Passwortkombinationen in das Backend einzuloggen. Es empfiehlt sich, die Ausgabe dieser Hinweisnachrichten zu unterbinden. Dafür fügt ihr den folgenden Aufruf in die functions.php eures Themes ein:
add_filter('login_errors',create_function('$a', "return null;"));
Der wp-admin Ordner
Es ist faktisch erwiesen, dass ein per HTTP-Authentifizierung geschützter oder auch einfach per IP-Whitelist unzugänglich gemachter WP-Admin-Ordner die Daten bei bestimmten Sicherheitslücken in WordPress (0days) vor Kompromittierung geschützt hätte. Ein Beispiel ist z.B. die SQL Injection in WordPress 3.1.3. Mit einem dementsprechend geschützten Admin-Ordner hätte ein Angreifer auch trotz der Sicherheitslücke keine Chance, diese auszunutzen. Vor Bruteforcing schützt das zwar nicht, da die wp-login.php weiterhin im Stammverzeichnis erreichbar ist, aber dafür werden zufällige Crawler und automatisierte Bots effektiv abgewehrt. Für nginx könnt ihr euch hier über eine passende HTTP-Authentifizierung mit optionaler IP-Whitelist informieren, bei Apache sieht es recht ähnlich aus (siehe auch Defense in Depth).
Die Versionsnummer (Meta-Tag)
Es ist nicht unbedingt notwendig, die WordPress-Version zu verbergen. Jeder halbwegs aktive Blog wird sehr wahrscheinlich auch immer die neueste WordPress-Version verwenden. Wer trotzdem auf Nummer sicher gehen möchte, kann einen kleinen Aufruf in die functions.php einfügen. Dieser verhindert, dass der Meta-Tag ‘Generator’ im Blog ausgegeben wird. Für den unwahrscheinlichen Fall, dass man mit einer älteren, angreifbaren Version fährt, erhält man ein wenig (Schein-)Sicherheit (vgl. Security through Obscurity). Fügt dafür den folgenden Aufruf in die functions.php eures Themes ein.
remove_action('wp_head', 'wp_generator');
Die Plugins und Themes sind das Gefährliche
Das alles nützt natürlich wenig, wenn man ‘password’ als Passwort verwendet oder seine PHP-Konfiguration willkürlich verhaut. Da das jetzt allerdings nichts mehr direkt mit WordPress selbst zu tun hat, werde ich das nicht extra erwähnen. Etwas anderes wird aber für viele um einiges interessanter sein: Das unsicherste jeder WordPress-Installation ist nicht WordPress selber, sondern die Themes/Plugins von Dritten, welche sich nicht an die Programmierrichtlinien halten. Demnach gilt es dadrauf einen besonderen Fokus zu setzen, so dass man z.B. ein flottes Source-Review durchführt. Ganz nach dem Motto “Minimize the Attack Surface” hilft es vielleicht am meisten, seine WordPress-Installation nicht mit tausenden, verschiedenen Plugins vollzustopfen. Auch die Installation einer WAF kann vor noch unbekannten Sicherheitslücken in Plugins und WordPress selber schützen.
WordPress <= 3.3.1 mit Sicherheitslücke? Aus Trustwave´s SpiderLabs Security Advisory TWSL2012-002 kann man verschiedene Sicherheitsbedenken für die aktuelle WordPress-Version entnehmen. Diese wurden allerdings nicht von WordPress als Sicherheitslücken anerkannt. Zurecht: Die hier bemängelten unzureichenden Sicherheitsvorkehrungen beziehen sich auf die Einrichtung einer neuen WordPress-Installation, welche nicht bei einem laufenden System auftreten können. Damit gilt das zwar im weitesten Sinne als potenziell gefährlich, ist aber in Wirklichkeit ein Problem des Nutzers, wenn dieser den WP-Ordner hochlädt ohne die Installation abzuschließen. Sollte man PHP dafür verantwortlich machen, wenn man eine phpinfo im Stammverzeichnis vergisst?