Mehr Sicherheit für WordPress mit einfachen Mitteln

Spam-Email von WordPress-Plugin Custom Content Type

Kein anderes Content Management System wird so intensiv angegriffen wie WordPress. Das liegt nicht an Mängeln des WordPress-Kerns selbst, sondern in erster Linie natürlich an der gewaltigen Verbreitung von WordPress und nicht zuletzt an den nicht immer genauso sicheren Plugins und Themes.

Gerade die unzähligen Erweiterungen machen WordPress verwundbar, Themes und Plugins können unerwünschte Schadsoftware einschleusen. Die eigene Webseite verkauft von heute auf morgen Pillen und lockt ins Abseits verseuchter Seiten. Ein Alptraum.

Plugins können die Sicherheit eines Systems natürlich deutlich verbessern, aber gleichzeitig sind Plugins zusätzliche Hintertüren. Fangen wir also mit kleinen Schritten in Handarbeit und ohne Programmierung an.

Alte WordPress-Installation und der Benutzername admin

Wenn eine alte WordPress-Installation vorliegt, kann der Administratorname noch admin sein. Da der Benutzername die Hälfte des Logins ausmacht, muss der Benutzername schleunigst in einen weniger offensichtlichen Namen geändert werden.

Der Benutzername kann nicht ohne Weiteres geändert werden: Einen neuen Benutzer anlegen, dem neuen Benutzer-Adminrechte zuweisen, probehalber mit dem neuen Benutzernamen anmelden und wenn alles gut geht, den Benutzer admin löschen.

Und so banal es klingt: ein nicht einfach zu erratener Benutzername sowie ein starkes Password sind der Schutzwall für die Webseite.

Dafür hat WordPress auch zwei Namen für jeden Benutzer: den unveränderlichen Benutzernamen und den Spitznamen. Öffentlich sichtbar ist der Spitzname, nicht der Benutzername.

Plugin- und Theme-Code-Editor deaktivieren

Die WordPress-Installation bringt einen Code-Editor mit, in dem die Dateien des Themes und Plugin-Dateien geändert werden können. In den falschen Händen ist der Theme-Editor eine Sicherheitsrisiko und es ist besser, wenn er in der wp-config.php abgeschaltet wird.

In die wp-config eine weitere Anweisung eintragen, um den Editor aus dem WordPress Dashbord zu entfernen.

define( 'DISALLOW_FILE_EDIT', true );

Updates

WordPress-Updates sind ein Klick auf einen Button und seit WordPress 3.7 die Einstellung auf ein automatisches Update.

WordPress liefert in regelmäßigen Abständen kleinere Updates, die automatisch durchgeführt werden können, nur die großen Updates müssen manuell in die Wege geleitet werden.

Wer allerdings viele Plugins installiert hat, muss nahezu täglich mit Plugin-Updates rechnen.

Für Plugins, die mehr als ein Jahr kein Update erfahren haben, sucht man besser nach einem frischen Ersatz. Von Zeit zu prüfen, ob ein altes Plugin, das zum letzten Mal 2013 bewußt zur Kenntnis genommen wurde, tatsächlich noch gebraucht wird.

It seems that perfection is attained not when there is nothing more to add, but when there is nothing more to remove.
Antoine de Saint Exupéry

»Setzt weniger Plugins ein« ist bereits ein Ruf der Sicherheitsexperten. 10 Must-Have-Plugins hingegen verstummt besser schleunigst.

WordPress-Version nicht anzeigen

Im Quelltext jeder WordPress-Seite finden Hacker die Versionsnummer. Besser hält WordPress sich da mit einem Eintrag in die Datei functions.php zurück.

functions.php
remove_action('wp_head', 'wp_generator');

Backup

Der nächste Schritt ist die Installation eines Backup-Plugins für den Worst Case. Das beste Backup nützt allerdings nichts, wenn es nicht regelmäßig an einen sicheren Ort geschafft wird. Der sichere Ort liegt am besten weitab vom eigenen Webspace.

Das kann ein Cloud-Speicher sein oder der eigene Rechner.

Die Backup-Lösung braucht eine Automatik, die z.B. für eine Seite mit hoher Änderungsfrequenz ein Update pro Tag sichert, und alte Backups nach einer Woche löscht. Eine alte und bewährte Backup-Technik speichert zusätzlich ein Backup pro Monat und behält diese Backups für mindestens drei Monate.

Zu jedem guten Backup gehört von Zeit zu Zeit ein Test, ob das Zurückspielen des Backups (Restore) wie erwartet gelingt.

Brute Force-Angriffe abwehren: Zwei-Faktor-Autorisierung

Unter einem Brute-Force-Angriff darf man sich nicht nur einen einsamen Hacker in einem dunklen Keller vorstellen, der die Login-Seite mit ausgedachten Namen und Passwörtern aufruft. Vielmehr sitzen hinter den wahrhaft gefährlichen Login-Versuchen Botnetzwerke, in denen ein ganzes Batalion von Rechner maschinelle Login-Versuche durchführt. Professionelles Hacken ist immer voll automatisiert.

Solche Angriffe finden immer und auf allen Seiten statt, manchmal milde, so dass man sie kaum oder gar nicht zur Kenntnis nimmt, manchmal so heftig, dass die Seite bei regulären Besuchern kaum noch Luft kriegt. Selbst die unauffälligste Webseite liegt unter diesem Dauerbeschuss, der sie in die Reihen des Botnetzwerks aufnehmen soll, um von dort aus die lukrativen Webseiten zu attackieren.

Die einfachste Abwehr der Login-Versuche ist ein vorgeschaltetes System-Login, das erfolgreich bewältigt werden muss, bevor die Login-Seite von WordPress geladen wird. Das vorgeschaltete Login bringt der Webserver bereits mit, es muss nur in Gang gesetzt werden: ein Eintrag in die Datei .htaccess und eine Datei .htpasswd, in die Benutzername und Passwort eingetragen werden.

Eintrag in die Datei .htaccess
<Files "wp-login.php">
  AuthName "Geschuetzter Bereich"
  AuthType Basic
  AuthUserFile /systempfad-zur-datei/.htpasswd
  require valid-user
</Files>

Die Datei .htpasswd muss angelegt werden und enthält pro Benutzer eine Zeile mit dem Benutzernamen im Klartext und dem verschlüsselten Passwort.

Loretta:$apr1$QTZ9NB21$e4zNaLrIfc4VQe1om71L71
Mauritius:$apr1$9FRCdcOA$ngDfUf8upuCAUB7TfBgsL/

Nichts verraten beim Login-Versuch

Die Fehlermeldung bei einem gescheiterten Login-Versuch ist mitteilsam und verrät, dass der Benutzername getroffen wurde. Damit ist die Hälfte der Barriere abgetragen.

Fehler: Das Passwort, das du für den Benutzernamen XXX eingegeben hast, ist nicht korrekt. Passwort vergessen?

Ein Eintrag in die functions.php des Themes verhindert den ungewollten Verrat.

function login_notes(){ return 'Anmeldedaten nicht korrekt.';}
add_filter( 'login_errors', 'login_notes' );

Verzeichnisse vor dem Ausspähen schützen

Wenn ein Verzeichnis angelegt wird und darin keine index.html- oder index.php-Datei liegt, bekommen Besucher des Verzeichnisses eine Liste aller Dateien vorgesetzt.

Haben wir z.B. ein Verzeichnis original und steuert jemand meineseite.de/original an, zeigt der Browser alle Dateien und Verzeichnisse unterhalb dieses Ordners. Dafür ist kein FTP-Zugriff, kein Passwort oder sonstwas nötig.

WordPress selber hat darum in allen Verzeichnissen, die Fremden nicht offenbart werden sollen (z.B. wp-content, themes, plugins, usw.), eine Datei index.php mit dem charmanten Hinweis

<?php
// Silence is golden.

Man kenn es WordPress entweder gleich tun und eine leere index.html oder index.php-Seite anlegen oder eine .htaccess-Datei mit einer Zeile in diesen Verzeichnissen anlegen:

Options All -Indexes

Dann zeigt das Verzeichnis anstelle der Dateiliste

Forbidden

You do not habe permission to access this document.


Web Server at meineseite.de

wp-config.php schützen

Hier liegen die sensiblen Zugangsdaten für die Datenbank. Das Verschieben der Datei config.php in das Verzeichnis über der WordPress-Installation ist ein weiterer kleiner Schritt zu mehr Sicherheit.

WordPress findet die wp-config ohne weitere Aktionen und Plugins im Verzeichnis über dem Installationsverzeichnis.

XML-RPC – stiller WordPress-Zugang und WordPress-Hintertür

XML-RPC ist eine zusätzliche Schnittstelle für die Kommunikation zwischen verschiedenen Systemen. Ohne diese Schnittstelle funktionieren einige Anwendungen nicht, die einen Zugriff auf die Webseite brauchen (z.B. das Schreiben von Beiträgen per Email). Aber nicht jeder Internet-Auftritt wird auch per Email oder aus einem anderen Programm heraus gepflegt.

Während die Login-Seite für ein reguläres Login jeweils einen HTTP-Request braucht, können über XML-RPC mit der system.multicall-Funktion Hunderte von Passwörtern mit wenigen Requests absetzen. xml-rpc.php ist darum ein beliebter und effektiver Angriffspunkt für Hacker, und wer auf diese Schnittstelle verzichten kann, verschließt eine gefährliche Hintertür.

Natürlich gibt es jede Menge Plugins, die den Zugriff auf die XML-RPC-Schnittstelle deaktivieren, aber der am wenigsten invasive Weg führt über die Datei .htaccess.

# Block WordPress xmlrpc.php requests
<Files xmlrpc.php>
   order allow,deny
   deny from all
</Files> 

Oder für einen NGINX-Server

# nginx block xmlrpc.php requests
location /xmlrpc.php {
   deny all;
}

oder

location ~* ^/xmlrpc.php$ {
   return 403;
}

Von einem Eintrag in die functions.php ist eher abzuraten, denn dort würde die Funktion bei einem Wechsel oder Update des Themes still und leise verschwinden.

Die Datei xmlrpc.php liegt im WordPress-Verzeichnis, aber das Löschen der Datei kann u.U. auch nur vorübergehend schützen, wenn die Datei mit einem WordPress-Core-Update zurückkehrt.

Sicherheitsschlüssel

Die Sicherheitsschlüssel liegen in der Datei wp-config.php. In älteren WordPress-Version sind die Einträge u.U. noch unversehrt.

define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');

Sicherheitsschlüssel schützen Cookies und Passwörter auf dem Weg zwischen Browser und Webserver und verschlüsseln sensible Daten. Statt sich selbst langatmige Schlüssel mit einer zufälligen Kombination von Zeichen und Ziffern auszudenken, kann man sich auf api.wordpress.org Schlüssel erstellen lassen und kopiert sie in die wp-config.php.

Security Plugins

Eine 100-prozentige Sicherheit gibt es nicht. Eine reiche Auswahl an Sicherheits-Plugins härtet WordPress über diese einfachen Eingriffe hinaus gegen Angriffe ab. Plugins wie Sucuri oder WordFence können wiederholte login-Versuche blockieren, Verzeichnisse nach Schadcode absuchen und sind meist schon mit den neusten Mustern von Angriffen vertraut.

Bei der Auswahl von Plugins stehen die Bewertungen der Benutzer helfend zur Seite. Weitere Faktoren sind: Wann war das letzte Update des Plugins? Wie oft ist es installiert?