WordPress ist ein sehr weit verbreitetes Blog-System, was natürlich die Attraktivität für potentielle Angreifer steigert. Die grundsätzliche Sicherheit des Systems ist hoch, wie eine Studie (PDF) des BSI – Bundesamt für Sicherheit in der Informationstechnik – im Juni 2013 ergeben hat. Trotzdem waren im April 2013 viele WordPress Installationen Ziel einer groß angelegten Angriffsaktion.
Dass dieser Angriff so erfolgreich war, liegt daran, dass viele Benutzer das System nicht individuell anpassen. Dadurch sind einem Angreifer viele Parameter bekannt, wie zum Beispiel der Pfad zum Login. Wird dann noch der Benutzernamen admin verwendet, kennt der Angreifer bereits zwei von drei Faktoren für einen erfolgreichen Login.
Bei dem oben genannten Angriff wurde genau dies ausgenutzt. Ein Botnetz hat gezielt nach WordPress-Systemen gesucht und es wurden Anmeldeversuche mit Benutzernamen admin durchgeführt. Da WordPress keinen Schutz gegen zu oft falsch eingegebene Passwörter bietet, war es nur eine Frage der Zeit, bis die Angreifer sich anmelden konnten.
Daher habe ich mir Gedanken gemacht, wie eine neue WordPress-Installation manuell besser abgesichert werden kann:
Sicherheitsschlüssel generieren
WordPress verwendet mehrere Sicherheitsschlüssel, um zum Beispiel Werte in Cookies zu schützen und als Salt für Sessions. Die Sicherheitsschlüssel werden in der Konfigurationsdatei wp-config.php, die sich im Hauptverzeichnis befindet, eingetragen. In der Beispiel-Datei von WordPress befinden sich schon die entsprechenden Platzhalter. Damit die Schlüssel nicht selbst generiert werden müssen, bietet WordPress dafür einen Dienst an. Das nachfolgende Beispiel zeigt solche Sicherheitsschlüssel (nicht verwenden – auf jeden Fall selber generieren):
define('AUTH_KEY', '2fv{),q=+5rHBz[]3aX@J_EK,~nN^H-)y8BV?6!kyVx8:3U'); define('SECURE_AUTH_KEY', 'R+pwJ9~+4i5E3oWJ2P`fcy-O6KXN+&v[5F.Oy2x/'); define('LOGGED_IN_KEY', 'q-T%h/1L9Rl8I=b/ubSiwP?J*ss5)O)F1^8h65ae9f'); define('NONCE_KEY', 'hNlwHx3L`7:X aPia3he?m`H*+)ke5E6%c[ua3s{@[iAl-'); define('AUTH_SALT', '&$VcU1/rneH~sU(?3o<%$Um61+(EY8c7NDQ#g2Ho}^v%h-h^/k&lQLh]#,C/Z}VLw6Zyx1*w}n');
Datenbanktabellen-Präfix ändern
Eine häufige Angriffsmethode ist das unerlaubte Einschleusen eines SQL-Befehls – auch SQL-Injection genannt. Wird solch eine Lücke von einem Angreifer gefunden, kann dieser darüber zum Beispiel das Passwort eines Benutzers ändern. Dieser Angriff gelingt aber nur, da der Tabellennamen wp_users bekannt ist. Um diese Angriffsfläche zu reduzieren, sollte das Tabellenpräfix wp_ geändert werden. Dazu muss der folgende Eintrag in der wp-config.php angepasst werden:
$table_prefix = 'wp_'; $table_prefix = 'beliebigerpraefix_';
Je komplizierter, und damit nicht mehr zu erraten, desto besser. Aber das gilt ja eigentlich für alles 😉
HTTPS für den Admin-Bereich erzwingen
Der Adminisitrationsbereich wird üblicherweise unverschlüsselt über HTTPS aufgerufen. Das ist besonders bei unsicheren Verbindungen, wie in einem öffentlichen W-LAN, sehr schlecht. Hier kann ein Angreifer (Stichwort ARP-Spoofing) oder ein böswilliger Hotspot-Betreiber den Benutzernamen und das Passwort abfangen. Daher sollte immer per HTTPS auf das Backend zugegriffen werden. In WordPress gibt es eine Funktion, damit die Verwendung von HTTPS für den Admin-Bereich erzwungen wird. Dieser Eintrag muss ebenfalls in die wp-config.php und kann direkt unterhalb des Datenbanktabellen-Präfixes eingetragen werden.
define('FORCE_SSL_ADMIN', true);
Login mit zusätzlichem Passwortschutz
Wie oben beschrieben, war das Ziel des Angriffes der Login-Mechanismus. Die einfachste Variante, um den Login zu schützen, ist die Verwendung eines zusätzlichen Passwortschutzes. Dies kann ganz einfach über die Standardfunktion des Webservers Apache realisiert werden. Dazu muss im Hauptverzeichnis die Datei .htaccess erstellt werden (normalerweise wird sie nach der Installation automatisch erstellt) und die folgenden Einträge hinzugefügt werden:
AuthName "Login" AuthType Basic AuthUserFile /server/pfad/.htpasswd require valid-user
In einer zusätzlichen .htaccess-Datei im wp-admin Ordner wird der folgende Eintrag hinzugefügt:
AuthName "Login" AuthType Basic AuthUserFile /server/pfad/.htpasswd require valid-user
Die .htpasswd-Datei mit dem Benutzernamen und dem Passwort kann zum Beispiel mit einem Generator erstellt werden und sieht dann beispielsweise so aus:
test:$1$WLNhPj@z$bM29xHYjseSZApc1YQ.hU/
Kann kein Passwortschutz per .htaccess eingerichtet werden, sollte zumindest keine Fehlermeldung bei einem fehlerhaften Anmeldeversuch ausgegeben werden. Wird die Fehlermeldung angezeigt, kann ein Angreifer erkennen, ob ein bestimmter Benutzernamen existiert. Die Meldung lässt sich durch einen Eintrag in der functions.php des verwendeten Themes deaktivieren:
add_filter('login_errors',create_function('$a', "return null;"));
Außerdem sollte in diesem Fall noch das Plugin Limit Login Attempts installiert werden. Damit kann die Anzahl der möglichen Versuche beschränkt werden, womit ein Ausprobieren des Passworts (Stichwort Bruteforce) nicht mehr möglich ist.
WordPress Generator Tag entfernen
Normalerweise steht im HTML-Quellcode einer generierten Seite von WordPress ein Meta-Tag-Eintrag mit der Version von WordPress. Angreifer können anhand dieses Eintrags die Version auslesen. Wenn es eine ältere, nicht aktualisierte Version von WordPress ist, kann der Angreifer nach bekannten und veröffentlichten Sicherheitslücken für diese Version suchen. Daher sollte der Eintrag der Versionsnummer entfernt werden. Dies geschieht über einen Eintrag in der functions.php des jeweiligen Themes.
remove_action('wp_head', 'wp_generator');
readme.html löschen
Eine weitere Datei, die noch entfernt werden muss, ist die readme.html. Sie liegt direkt im Hauptverzeichnis einer WordPress-Installation. In dieser Datei steht auch die Versionsnummer. Da die Datei license.txt nicht im Produktiveinsatz benötigt wird, kann sie entfernt werden. In der deutschen Version sollte noch die deutsche Übersetzung der Datei, die liesmich.html, entfernt werden.
Zwar kann immer noch die WordPress-Version herausgefunden werden, z. B. über das Vorhandensein von bestimmten Dateien, die in einer speziellen Version hinzugefügt worden sind, aber zumindest für Skriptkiddies ist es ein weiteres Hindernis.
Benutzername und Passwort
Nach einer erfolgreichen Installation sollte ein neuer Benutzer mit Administrations-Zugriffsrechten angelegt werden. Um die Sicherheit zu erhöhen, sollte als Benutzernamen ein individueller Name und nicht „admin“ oder ähnliches verwendet werden. Natürlich sollte noch ein sicheres Passwort gewählt werden. Jetzt muss noch der ursprüngliche Admin-Benutzer gelöscht werden. Damit ist der bekannte Benutzernamen „admin“ nicht mehr vorhanden und die standardmäßige Benutzer-ID „1“ wird nicht mehr verwendet. Dies reduziert wieder die mögliche Angriffsfläche.
Fazit WordPress Sicherheit
Wurden alle Schritte umgesetzt, nur sichere Passwörter verwendet und werden WordPress und alle Erweiterungen regelmäßig aktualisiert, sind Standard-Angriffe wie im April keine Gefahr mehr. Hier wird der neue automatisierte Update-Mechanismus der Version 2.7 sicher einige Angriffsszenarien aushebeln. Absolute Sicherheit gibt es zwar nicht, aber als Blog-Betreiber kann man es Angreifern möglichst schwer machen. Denn auch für Angreifer gilt, Aufwand und Nutzen müssen zueinander passen.
Hier gibt es noch weitere Tipps, um WordPress sicherer zu machen:
Sicherheit in WordPress: 10 Schritte zum Schutz des Admin-Bereichs
WordPress mit wenigen Kniffen absichern
Mehr Sicherheit für WordPress
Tipps zur Sicherheit von WordPress
Mehr Sicherheit für WordPress Software – WordPress sicher machen
Danke für die guten Hausmittelchen 🙂
Bin immer offen für sowas und tu mich dennoch sehr schwer mit dem Implementieren… doch du hast das echt gut erklärt!
Top Artikel, Schicker Blog, was will man mehr ?
Grüße Sarah