WordPress Sicherheit

WordPress Sicherheit – Schutz für deine Website

Frage: Kann ich mit WordPress eine sichere Website erstellen? Um es vorweg zu nehmen – Ja. Das beliebteste CMS auf dieser Erde ist Open Source und jeder kann sich nach Belieben im Quelltext umsehen. Diesen angenehmen Umstand machen sich leider auch die bösen Buben im Netz zu Eigen.

Gerade wenn es um gewerbliche genutzte WordPress-Installationen geht, ist oftmals schon im Planungsprozess die Frage nach der Sicherheit eine der ersten und relevantesten. Für all meine Kunden (und die es noch werden wollen 😉 ) hier eine Checkliste um WordPress sicher zu installieren und zu betreiben.

WordPress ist von Haus aus sicher. Hunderte von engagierten Entwicklern schrauben regelmäßig am WordPress Core, erweitern diesen und sind immer auf Sicherheit bedacht. Dennoch gibt es einiges, was du selbst zur Sicherheit deiner WordPress Installation beitragen kann. Denn auch bei WordPress gilt: 99% aller Fehler sitzen vor dem Bildschirm.

WordPress Sicherheit – die Tipps:

  1. Backup, Backup, Backup
  2. Benutzernamen, Passwörter und Rollen
  3. Updates ausführen sobald sie angeboten werden
  4. Abschalten der Login-Fehlermeldungen
  5. Den Admin Bereich schützen
  6. Die Dateibearbeitung verhindern
  7. Auf unnötige Plugins verzichten
  8. SSL verwenden
  9. Augen auf bei der Wahl von Themes und PlugIns
  10. Präfixe aller Tabellen in der Datenbank ändern
  11. Registrierung ausschalten
  12. Script Injection verhindern
  13. WordPress Versionsnummer entfernen
  14. Schwarze Liste für Bots und böse Buben
  15. XML-RPC Schnittstelle abschalten
  16. Plugin Verzeichnis schützen
  17. Verzeichnisse wp-content und wp-includes mit eingeschränkten Zugriffsrechten
  18. Abschalten der REST-API

 

1. Backup, Backup, Backup

Bereits vor einer WordPress Installation solltest du dir Gedanken über eine zukünftige und effiziente Backupstrategie machen. Alle Dateien und die Datenbank sollten regelmäßig gesichert werden. Leider erlebe ich es immer wieder, dass aus Kostengründen, aus Gründen der Bequemlichkeit oder der Gedanke “Ich bin eh nicht so wichtig, wer sollte mich hacken?” sehr selten Backups angelegt werden. Gar keine Backups habe ich auch schon erlebt. Wenn dann aber der Ernstfall eintritt, ist das Rumgeheule groß und der Webmaster soll’s wieder richten (Wenn sich für diesen Fall einer finden lässt!).

Dabei muss WordPress nicht unbedingt Opfer eines Angriffs geworden sein. Schon ein fehlerhaftes Update eines schlampig programmierten Plugins kann ganze Installationen in die Knie zwingen. Und wenn es sich dabei auch noch um eine Multisite Installation handelt (mehrere Domains mit einer WordPress-Installation betreiben), na dann gute Nacht.

Zu einer erfolgreichen und sicheren Backupstrategie ein paar Empfehlungen:

  1. Vor jedem Update ein Backup aller Dateien und der Datenbank (auch vor Aktualisierungen von PlugIns).
  2. Niemals das Backup auf dem gleichen Server (schlimmer noch: innerhalb der WordPress Installation) speichern. Am Besten sendet man Backups an eine extra hierfür eingerichtete E-Mail Adresse oder direkt in eine Cloud (z.B. Google Drive , Amazon S3 oder Dropbox ) . Wer den großen Cloud Anbietern nicht traut, kann auch eine Own Cloud Lösung im eigenen Haus in Betracht ziehen um Backups zu speichern.
  3. Regelmäßiges Backup – die beste Backupstrategie nutzt nur etwas, wenn Sicherungen regelmäßig durchgeführt werden. Hierbei leisten Backup Plugins wie BackWPup sehr gute Dienste. Je nach Aufkommen und Aktualisierungsbedarf können beliebige Intervalle zur Datensicherung eingestellt werden.

Backups sind ein wichtiger Schritt für deine WordPress Sicherheit.

2. Benutzernamen, Passwörter und Rollen

Bitte immer Benutzernamen und Passwörter verwenden, die nur speziell für eine WordPress Installation gültig sind. Damit ist gemeint, dass nicht das Passwort von anderen Diensten wie z. B. Google, Amazon, web.de, Microsoft usw. verwendet werden sollte. Ist hier mal ein Datenklau erfolgreich gewesen, so ist es für die Hacker und Bots ein Leichtes, diese Daten auch bei WordPress erfolgreich zu verwenden.

Als Benutzernamen niemals eine bekannte oder anderswo verwendete E-Mail Adresse verwenden. Bitte stets “echte” Benutzernamen verwenden wie z.B. “litleJoe”, “roteBanane”, “Superwomen” usw. Was ein sicheres Passwort ist (und was nicht) muss ich hier nicht weiter vertiefen. Hier liefert eine entsprechende Suchanfrage in Suchmaschinen wertvolle Tipps.

Sollte in einer in die Tage gekommenen WordPress Installation noch der Benutzername “admin” vorhanden sein, so muss dieser schnellst möglich geändert werden. Er ist immer noch erste Wahl wenn es darum geht, einen WordPress Zugang zu kapern. Dies lässt sich relativ einfach über eine SQL-Abfrage an die Datenbank ändern:


UPDATE wp_users
SET user_login = 'Batman' 
WHERE user_login = 'admin';

Mit dieser Anweisung wurde der Benutzername “admin” in “Batman” geändert. Leider werden die bis dato unter dem Benutzernamen “admin” erstellten Beiträge nicht automatisch dem neuen Benutzernamen “Batman” zugeordnet.

Die Rolle des Administrators sollte nur einmal vergeben werden. Bedenke die Vergabe der Rollen sehr sorgfältig und kommuniziere deine Absichten gegenüber anderen Mitarbeitern. Begründe diese Sicherheitsmaßnahme und lass nicht den Eindruck von Misstrauen aufkommen. Hinweise zu den einzelnen Rollen findest du im WordPress Support.

3. Updates ausführen sobald sie angeboten werden

Da WordPress bekanntlich Open Source ist, werden immer wieder Updates zur Verfügung gestellt. Kleinere Updates werden meist automatisch installiert. Für größere Release Updates muss das Update manuell gestartet werden. Dies sollte immer zeitnah nach Veröffentlichung der Updates geschehen. Auch für Plugins und Themes sollten Updates immer schnellst möglich ausgeführt werden. Updates sind wichtig, wenn es um die Sicherheit einer WordPress Installation geht.

4. Abschalten der Login-Fehlermeldungen

WordPress hat die etwas seltsame Angewohnheit, bei einem gescheiterten Login-Versuch mal kurz horizontal hin- und herzuwackeln und uns eine Meldung zu präsentieren. Mit dem Zucken können wir vielleicht noch Leben, aber nicht mit dem Inhalt der Fehlermeldung. Wurde lediglich das Passwort falsch eingegeben, aber der Benutzername stimmt, dann präsentiert uns WordPress einen Satz im Stil “FEHLER: Das Passwort, das du für den Benutzernamen Batman eingegeben hast, ist nicht korrekt”. Was sagt das dem Hacker? Treffer – den Benutzernamen hat er schon mal, eine Unbekannte weniger. Jetzt muss er nur nach ans Passwort kommen. Diese Fehlerausgabe lässt sich aber relativ simple mit einem Einzeiler in der functions.php des verwendeten Themes abstellen.


add_filter('login_errors', create_function('$a', "return null;"));

Das Zucken bleibt zwar weiterhin, aber es werden keine Informationen mehr ausgegeben, ob der Benutzername beim falschen Login richtig war. Wieder ein bisschen sicherer unser WordPress.

5. Den Admin Bereich schützen

Ein weiterer effektiver Schutz ist das Absichern des Ordners “wp-admin” bzw. der gesamten Administrationsoberfläche mittels einer .htaccess Datei. Hierbei wird das Verzeichnis mit einem weiteren Benutzernamen und Passwort geschützt. Diese Authentifizierung erfolgt auf Serverebene, also noch vor dem eigentlichen WordPress-Login.
Aber eins muss hierbei beachtet werden: Werden im Theme Ajax Abfragen durchgeführt, so muss folgender Eintrag in die .htaccess Datei im root Verzeichnis der WordPress-Installation hinzugefügt werden:


<Files admin-ajax.php>
Order allow,deny
Allow from all
Satisfy any
</Files>

Die Datei “admin-ajax.php” befindet sich im Verzeichnis “wp-admin”. Da dies durch .htaccess geschützt ist, wird durch genannte Direktive der Zugriff über das Frontend (das Theme) explizit auf diese eine Datei erlaubt. Somit kann die benötigte Ajax-Funktionalität aus dem WordPress Backend im Frontend eingebunden und verwendet werden.

6. Die Dateibearbeitung verhindern

Standardmäßig bietet WordPress die Möglichkeit, alle Dateien eines Themes direkt in einem Texteditor zu bearbeiten. Ich muss hier nicht weiter darauf eingehen was passiert, wenn der Editor in falsche Hände gerät. Dieser gehört abgeschaltet.


define('DISALLOW_FILE_EDIT', true);

Mit dem Aktivieren dieser Option in der “wp-config.php” ist der Editor und der Zugriff darauf deaktiviert. Der Editor ist nicht mehr im Admin Bereich verfügbar.

7. Auf unnötige Plugins verzichten

Wie schon beschrieben, wollen auch PlugIns unsere Aufmerksamkeit, wenn es um die Sicherheit bei WordPress geht. Es gibt PlugIns die nicht unbedingt benötigt werden. Wenn z.B. nur wenig mit Tabellen gearbeitet wird, muss nicht unbedingt ein spezielles PlugIn für Tabellen installiert werden. Man kann mit gut vorbereitetem CSS im Theme und einer Editor Erweiterung wie z.B. dem TinyMCE Advanced schon sehr viel erreichen. Dieser hat eine Tabellenbearbeitung schon mit an Bord.
Ich halte z.B. auch ein PlugIn zum Einfügen für Google Analytics zum Seitentracking für nicht unbedingt notwendig. Der von Google bereitgestellte Code ändert sich eigentlich nie, so kann man ihn auch direkt an passender Stelle im Theme platzieren.
Oder auch das in die Mode gekommene “Scroll to Top”: meist befindet sich rechts unten ein Icon, welches eingeblendet wird, wenn eine bestimmte Anzahl an Pixeln im Browser gescrollt wurde. Ein Klick hierdrauf und man gelangt schnell wieder zum Seitenanfang. Auch dieser Knopf wird nicht ständig geändert und er lässt sich mit ein paar Zeilen JavaScript und CSS vom Theme-Entwickler recht schnell umsetzen. Auch hierfür braucht man nicht unbedingt ein PlugIn.

8. SSL verwenden

Wenn der Server der WordPress Installation SSL bereitstellt, so gibt es keine Ausrede es nicht zu verwenden. Die Verwendung von SSL Zertifikaten ist ein enormer Schritt auf der Sicherheitsleiter nach oben. Auch surft es sich als Besucher einer Seite mit einem Schloss Symbol neben der URL im Browser wesentlich beruhigter. Es ist auch möglich, nur den Admin-Bereich über SSL abzusichern (aus welchen Gründen auch immer). Dies muss man WordPress mit einem Eintrag in der “wp-config.php” mitteilen:


define('FORCE_SSL_ADMIN', true);

Damit veranlasst man WordPress, dass beim Zugriff auf die Administrationsoberfläche immer SSL Verbindungen verwendet werden.

9. Augen auf bei der Wahl von Themes und PlugIns

Schon mit der Wahl eines Themes fängt die Sicherheit bei WordPress an. Einige Punkte gibt es bei der Auswahl eines zu beachten: Wie ist der Stand der letzten Aktualisierung? Wurden überwiegend positive Bewertungen und Rezensionen abgegeben? Gibt es einen Support oder ein Forum dazu? Das gleiche gilt auch für PlugIns. Hier kommt noch der Faktor der Aktualisierungen hinzu. Wurde das PlugIn schon mit der aktuellsten WordPress Version getestet? Wer nicht ganz blauäugig an die Wahl von Themes und PlugIns herangeht, hat für seine WordPress Sicherheit schon viel getan.

10. Präfixe aller Tabellen in der Datenbank ändern

Falls nicht schon bei der Installation WordPress geschehen, sollten alle Tabellen-Präfixe geändert werden. Standardmäßig setzt WordPress bei der Installation den Präfix “wp_” vor jede Tabelle. Das wissen auch die, die uns mit SQL-Injections ärgern wollen. Kleines Beispiel:
In einem schlecht programmierten PlugIn befindet sich in einer Datei “config.php” folgender Eintrag:


"SELECT * FROM ".$wpdb->prefix."tabelle_user WHERE id=".$_pid

In dieser Abfrage wird die Variable $_pid ungefiltert an die Datenbank gesendet. Woher weiß der Angreifer, dass in diesem PlugIn in genau dieser Datei solch ein Code vorhanden ist? Ganz einfach – der Angreifer kann, wie jeder andere auch, einfach das PluIn runterladen und in aller Ruhe im Code stöbern.

Der Hacker nutz das dann so aus:


http://meineseite.de/wp-content/plugins/plugin-xxx/config.php?
pid={böse Abfrage}

Und “böse Abfrage” enthält folgendes:


SELECT * FROM $wpdb->prefix.tabelle_user 
WHERE id=-1 union Select 1,2,3,{usw.},
group_concat(user_login,0xa,user_pass),4,5,6,{usw.} from wp_users

Als Ergebnis erhält man eine schöne Ausgabe mit Benutzernamen und E-Mail-Adressen. Nun noch den Aktivierungscode ermitteln:


-1 union Select 1,2,3,{usw.},group_concat
(user_login,user_activation_key),4,5,6,{usw.} from wp_users

und schon hat man die Ausgabe mit den benötigten Aktivierungscodes um ein neues Paswort zu generieren.
Der Link hierzu ist relativ simple:
http://meineseite.de/wp-login.php?action = rp&key=Aktrivierungscode&login = Benutzername
Somit kann das Passwort zurückgestzt werden und der Angreifer hat vollen Zugang auf die WordPress Administrationsoberfläche. Und Erfolg hatte der Angreifer nur, weil die Tabelle “users” den Standard Präfix “wp_” hatte. Also unbedingt Tabellennamen ändern, wenn nicht bereits geschehen.

11. Registrierung ausschalten

Wenn es nicht nötig ist, dass sich Benutzer registrieren können, dann bitte entsprechende Registrierung deaktivieren. Dazu besucht man im Backend die EINSTELLUNGEN -> ALLGEMEIN und entfernt das Häkchen vor “JEDER KANN SICH REGISTRIEREN”.

12. Script Injection verhindern

Um Manipulationen der globalen PHP Variablen _REQUEST und GLOBALS zu verhindern, kann man folgenden Eintrag in der .htaccess Datei vornehmen:


Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]

Obiger Eintrag in der .htaccess Datei überprüft, ob ein “<script>-Tag” in der URL (QUERY_STRING) vorhanden ist und ob hiermit versucht wurde, GLOBALS oder _REQUEST zu manipulieren. Ist einer dieser Fälle eingetreten, wird auf die index.php umgeleitet und eine Fehlermeldung ausgegeben.

13. WordPress Versionsnummer entfernen

WordPress hat die Angewohnheit, seine aktuelle Versionsnummer im Quelltext einer Website auszugeben:


<meta name="generator" content="WordPress 4.0" />

aha, Version 4. 0! Der Hacker weiß nun, was es in dieser Version für Schwachstellen gab und versucht diese nun für seine Zwecke zu missbrauchen. Der Eintrag


remove_action('wp_head', 'wp_generator');

in der functions.php verhindert das erscheinen einer WordPress Versionsnummer im Quelltext.

14. Schwarze Liste für Bots und böse Buben

Mit folgendem Eintrag in der .htaccess kann bestimmten IP Adressen der Zugriff verweigert werden:


<Limit GET POST PUT>
order allow,deny
allow from all
deny from 987.654.321
deny from 123.456.789
deny from 111.222.333
</LIMIT>

Hinweis: Die genannten IP-Adressen sind fiktv und sollten nicht verwendet werden.

15. XML-RPC Schnittstelle abschalten

Was ist die XML-RPC Schnittstelle? Sie dient zur Verwaltung von Inhalten. Damit ist es z.B. möglich, über Apps auf Smartphone, Tablet oder Desktop WordPress zu verwalten und Artikel zu verfassen. Auch Pingbacks werden durch diese Schnittstelle ermöglicht. Da die verantwortliche Datei “xmlrpc.php” im passwortgeschützten Bereich von WordPress liegt, ist sie ein beliebtes Angriffsziel. Angreifer können sich in Kombination mit weiteren WordPress Funktionen ruckzuck Username und Passwort Paare liefern lassen. Wer auf die beiden genannten Punkte verzichten kann, weil er Artikel eh im Backend verfasst und keine Pingbacks möchte, sollte auf jeden Fall die XML-RPC mit folgender Anweisungen in der functions.php abschalten:


add_filter( 'xmlrpc_enabled', '__return_false' );

Damit ist die Schnittstelle deaktiviert. Sie muss aber noch aus dem HTTP-Header der Website gelöscht werden. Folgende Ergänzung ist der functions.php hinzuzufügen:


add_filter( 'wp_headers', 'if_remove_x_pingback' );
 function if_remove_x_pingback( $headers ) {
 	unset( $headers['X-Pingback'] );
 	return $headers;
 }

Damit ist der HTTP-Header vom Eintrag der XML_RPC Schnittstelle bereinigt. Zuletzt ist noch der Zugriff auf die “xmlrpc.php” via .htaccess zu unterbinden. Der Eintrag sollte oberhalb der Zeile “#Begin WordPress” erfolgen:


<Files xmlrpc.php>
order Deny, Allow
Deny from all
</Files>

Die XML-RPC Schnittstelle der WordPress Installation ist nun Geschichte.

16. Plugin Verzeichnis schützen

Ein weiterer Schritt Richtung WordPress Sicherheit: wenn nicht schon durch die .htaccess Datei geregelt, sollte der Zugriff auf ein Liste der verwendeten Plugins verweigert werden. Dies erreicht man durch Hinzufügen einer leeren index.php ins Verzeichnis “wp-content/plugins”. Sollte eine alte Apache Konfiguration noch die Ausgabe von leeren Verzeichnissen zulassen, so ist man hiermit davor geschützt.

17. Verzeichnisse wp-content und wp-includes mit eingeschränkten Zugriffsrechten

Mit jeweils einer .htaccess Datei in den Verzeichnissen “wp-content” und “wp-includes” werden Zugriffe nur auf bestimmte Dateitypen erlaubt. Hier gilt aber Vorsicht: sollte ein Plugin Zugriff auf einen hier nicht aufgeführten Dateityp benötigen (z.B. php), so muss der Eintrag entsprechend angepasst werden.


order Deny, Allow
Deny from all
<Files ~ ".(png|gif|jpe?g|js|css)$">
Allow from all
</Files>

18. Abschalten der REST-API

Die REST-API von WordPress ermöglicht den Informationsaustausch zwischen verschiedenen Systemen. Die REST-API kann genutzt werden, um Informationen auf Servern verteilen und über einen HTTP-Request anzufordern. Über diese API können WordPress Seiten aber auch manipuliert werden. Um die REST-API zu deaktivieren und auch eine entsprechende Ausgabe im Header Quelltext der Seite zu unterbinden, fügt man der functions.php folgende Zeilen hinzu:


add_filter('rest_enabled', '_return_false');
add_filter('rest_jsonp_enabled', '_return_false'); 
function if_remove_api () {
 remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
 remove_action( 'wp_head', 'wp_oembed_add_discovery_links', 10 );
}
add_action( 'after_setup_theme', 'if_remove_api' );

Stephan Funke

Nun bist Du an der Reihe! Wenn Dir dieser Beitrag gefällt, dann hinterlasse doch einen Kommentar, den davon lebt dieser Blog. Werde Fan auf Facebook oder folge mir auf Google+ und Twitter und bleibe somit immer auf dem Laufenden, wenns hier was neues gibt. Oder teile diesen Beitrag einfach. Ich bin Euch für jede Art von Unterstützung dankbar.

2 Kommentare

Kommentarfunktion geschlossen!