WordPress absichern

  • Standardmäßig ist das Tabellenpräfix von WordPress »wp_«. Ihr könnt das Prefix bspw. auf 12eeXk98_wp_ ändern. Damit reduziert ihr die Wahrscheinlichkeit einer SQL-Injections, die gezielt auf das »wp_« Tabellenpräfix ausgerichtet ist. Doch Vorsicht bei diesem Eingriff! Am einfachsten ist es, den Wert noch bei der WordPress-Installation anzupassen. Ansonsten sind später Änderungen in der Datenbank und der »wp-config.php« notwendig.

table_prefix

4.3 Backups

Eure WordPress-Installation wurde von einem Angriff kompromittiert? Ihr habt durch eine kleine Unachtsamkeit wichtige Dateien gelöscht? Ein Plugin hat euch die komplette Webseite zerschossen? Ärgerlich – aber mit einem Backup seid ihr auf der sicheren Seite. Vor jedem Update einer WordPress-Installation und zu festgelegten Zeitpunkten sollten Backups durchgeführt werden. Dazu eignet sich zum Beispiel das Plugin BackUpWordPress oder BackWPup-Plugin. Neben den Seiten, den Konfigurationsdateien, Themes und Plugins wird ebenfalls ein Backup von der Datenbank erstellt.

Backups sind Pflicht! Nach jedem Backup-Durchlauf solltet ihr euch die Daten auf euren Rechner herunterladen und dort sicher verwahren.

4.4 TLS-Verschlüsselung (ehemals SSL)

Es existieren verschiedene Arten von TLS-Zertifikaten. Ein TLS-Zertifikat bzw. die TLS-Verschlüsselung ermöglicht eine verschlüsselte Kommunikation zwischen WordPress und eurem Browser – Passwörter für die Anmeldung im Dashboard lassen sich somit nicht von einem Angreifer mitlesen. Falls euer Anbieter bzw. Hoster TLS-Zertifikate unterstützt, solltet ihr eines beantragen. Je nach Vertragsdauer belaufen sich die Kosten auf ca. 25 – 60 € pro Jahr für eine Domain. Alternativ könnt ihr bei Let’s Encrypt ein kostenloses Zertifikat beantragen – falls dies bei eurem Hoster möglich ist, dann solltet ihr diese Variante wählen.

Um sicherzustellen, dass eure Kommunikation nach der Integration eines TLS-Zertfikats verschlüsselt stattfindet, solltet ihr in der Datei »wp-config.php« folgende Änderung vornehmen:

define('FORCE_SSL_ADMIN', true);

Mit »FORCE_SSL_ADMIN = true« wird neben dem Anmeldeprozess die gesamte Admin-Session verschlüsselt. Dazu zählen neben dem Passwort für die Anmeldung auch die Cookies. Seit WordPress 4.x ist der Paramater »FORCE_SSL_LOGIN = true« übrigens veraltet und wird vollständig durch »FORCE_SSL_ADMIN = true« ersetzt.

3. Howto: Apache .htaccess

Wichtig: Damit das Code-Snippet funktioniert, muss euer Hoster die Verwendung von .htaccess Konfigurationsdateien erlaubt haben bzw. die AllowOverride-Direktive (AuthConfig) korrekt gesetzt haben. Funktioniert das Code-Snippet also nicht, dann fragt euren Provider, ob ihr Eingriffe über eine .htaccess vornehmen dürft. Sollte dies nicht der Fall sein, dann wäre ein Wechsel zu einem anderen Hoster angeraten.

Solltet ihr nicht über einen eigenen Server verfügen ist die Wahrscheinlichkeit hoch, dass euer Webhoster auf Apache zurückgreift. Mindestvoraussetzung für die Anleitung ist eine Hosting-Umgebung bei der Zugriff auf das Webverzeichnis besteht. Dann könnt ihr im Normalfall .htaccess Dateien verwenden, um diverse Schutzmaßnahmen zu implementieren. Für den Schutz des Login-Bereichs sind folgende Schritte notwendig:

  • Zunächst wird im Hauptverzeichnis eures Blogs eine Datei mit dem Namen ».htpasswd« angelegt.
  • Anschließend wird die ».htpasswd« Datei mit Inhalt gefüllt. Nutzt dazu den .htpasswd Generator. Wählt einen Usernamen und ein sicheres Passwort (bspw. 20 Zeichen). Als Hashing-Verfahren selektiert ihr »bcrypt« mit einer Cost von »11«. Die Ausgabe des Generators kopiert ihr anschließend in die eben angelegte ».htpasswd« und speichert die Datei ab.
  • Ebenfalls im Hauptverzeichnis legt ihr eine weitere Datei mit dem Namen ».htaccess« an (eventuell ist diese auch schon vorhanden, dann ergänzt ihr sie). Kopiert das untenstehende Code-Snippet und fügt es hinter »# END WordPress«  in die Datei ein.
  • Wichtig: Anschließend müsst ihr noch den genauen Pfad zur User- bzw. Passwortdatei ».htpasswd« unter AuthUserFile anpassen. Falls ihr damit Probleme habt könnt ihr den Pfad mit dem PHP-Schnipsel ermitteln. Wird der Pfad falsch gesetzt, kommt es bspw. zum Internal Server Error 500 oder ähnliches.

3.1 Apache Code-Snippet

Hinweis: Beachtet die Änderungen ab dem Apache 2.4.

# Bis einschließlich Apache 2.3
# Auth protect wp-login.php
<Files wp-login.php>
   AuthType Basic
   AuthName "Restricted Admin-Area"
   AuthUserFile /pfad/zur/.htpasswd
   Require valid-user
</Files>
# Deny access to important files
<FilesMatch "(\.htaccess|\.htpasswd)">
   Order deny,allow
   Deny from all
</FilesMatch>

# Ab Apache 2.4
# Auth protect wp-login.php
<Files wp-login.php>
   AuthType Basic
   AuthName "Restricted Admin-Area"
   AuthUserFile /pfad/zur/.htpasswd
   Require valid-user
</Files>
# Deny access to important files
<FilesMatch "(\.htaccess|\.htpasswd)">
   Require all denied
</FilesMatch>

Code-Snippet kurz erklärt:

  • Files: Unter Files wird die zu schützende Datei definiert. Erst nach einer erfolgreichen Authentifizierung gegenüber dem Webserver kann die »wp-login.php« aufgerufen werden.
  • AuthType: Mit AuthType Basic wird die Authentifizierungsmethode gegenüber dem Webserver definiert. Bei dieser Methode wird der Username und Passwort unverschlüsselt übertragen – daher solltet ihr den Admin-Bereich immer über eine TLS-verschlüsselte Verbindung aufrufen. Ansonsten könnte jemand die Anmeldedaten mitschneiden. Im zweiten Teil der Artikelserie habe ich das bereits kurz erläutert.
  • AuthName: Der AuthName legt fest wie der geschützte Bereich heißen soll.
  • AuthUserFile: Unter AuthUserFile wird der Pfad zur ».htpasswd« festgelegt.
  • require: Jeder User (valid-user) der in der ».htpasswd« definiert wurde erhält nach Eingabe des korrekten Passworts Zugang zur »Restricted Admin-Area«.
  • FilesMatch: Unter FilesMatch verbieten wird jeglichen Zugriff von außen auf die soeben angelegten Dateien ».htaccess« und ».htpasswd«. Eine Vorsichtssmaßnahme, damit keiner deren Inhalt auslesen kann.

4. Directory Browsing unterbinden

Standardmäßig sollte das Directory Browsing aus Sicherheitsgründen ausgeschaltet sein. Es ermöglicht die automatische Ausgabe eines Inhaltsverzeichnisses von Dateien und Ordnern auf dem Webspace. Da WordPress weit verbreitet ist kennen viele die Dateistruktur und verschaffen sich durch Aufrufe wie »www.domain.de/wp-content/plugins« einen Einblick in die verwendeten Plugins – Directory Browsing gilt es daher zu deaktivieren.

4.1 Apache

# Prevent Directory Listings
Options -Indexes

Die Modifikation ist in der .htaccess Datei im Root-Verzeichnis von WordPress durchzuführen.

6. Admin Zugang auf IP-Adresse beschränken

Im Beitrag .htaccess Schutz – WordPress absichern Teil4 habe ich euch vorgestellt, wie der Admin-Bereich von WordPress mit einem Zugriffsschutz abgesichert werden kann. Durch die Limitierung auf eine IP-Adresse wird der Zugangsbereich zusätzlich geschützt – Zugriff erhalten dann lediglich autorisierte IP-Adressen. Problematisch wird es bei ständig wechselnden IP-Adressen, aber auch hierfür gibt es eine Lösung. Apache kann IP-Adressen über ihren Domain Namen auflösen.

Einfaches Beispiel:
Mit dem pingdig oder host Befehl könnt ihr die IP-Adresse zum jeweiligen Domain Namen herausfinden. Ein ping auf web.de:

Ping

Die Domain web.de löst also auf die IP-Adresse 212.227.222.8 auf. Eine Anfrage auf einen Domain Namen funktioniert damit ähnlich einer Telefonauskunft.

Mittels Dynamic DNS lässt sich das Problem der ständig wechselnden IP-Adresse lösen. Dadurch wird der Rechner immer über den selben Domainnamen erreichbar bzw. Apache führt ein DNS Lookup durch und erhält die dazugehörige IP-Adresse. Über eine FRITZ!Box könnt ihr euch recht fix ein Dynamic DNS Eintrag einrichten. Dazu hatte ich einen Artikel (Fritzbox 6360 Dynamic DNS mit Two DNS als Anbieter) verfasst, der sich im speziellen mit dem Anbieter TwoDNS befasst.

6.1 Apache

# Bis einschließlich Apache 2.3
# Protect wp-login.php
<Files wp-login.php>
   Order deny,allow
   Deny from all
   Allow from [DYNAMIC.DNS.NAME]
</Files>

# Ab Apache 2.4
# Protect wp-login.php
<Files wp-login.php>
   Require host example.org
</Files>

[DYNAMIC.DNS.NAME] dient als Platzhalter für den Domain Namen, den ihr beim Dynamic DNS Anbieter registriert habt. Die Modifikation ist in der .htaccess Datei im Root-Verzeichnis von WordPress durchzuführen.

Ihr könnt das Code-Snippet auch mit dem Zugriffsschutz kombinieren:

# Bis einschließlich Apache 2.3
# Protect wp-login.php
<Files wp-login.php>
   Order deny,allow
   Deny from all
   AuthType Basic
   AuthName "Restricted Admin-Area"
   AuthUserFile /pfad/zur/.htpasswd
   Require valid-user 
   Allow from [DYNAMIC.DNS.NAME] 
</Files>

# Ab Apache 2.4
# Protect wp-login.php
<Files wp-login.php> 
   AuthType Basic
   AuthName "Restricted Admin-Area"
   AuthUserFile /pfad/zur/.htpasswd
   Require valid-user 
   Require host example.org
</Files>

7. Direkte Ausführung von PHP-Dateien unterbinden

Oftmals ist der Uploads Ordner unter »/wp-content/uploads« ein beliebtes Einfallstor für Angreifer, da dieser in den meisten Fällen beschreibbar sein muss. Mit cleveren Tricks oder unter Ausnutzung von Sicherheitslücken (bspw. WordPress Asset-Manager PHP File Upload Vulnerability, WordPress File Uploader Plugin PHP File Upload Vulnerability) werden PHP-Dateien in Verzeichnisse geladen und dort dann ausgeführt. Eine direkte Ausführung von PHP-Dateien in den Unterordnern »/wp-content« oder »/wp-includes« kann dieses Angriffsszenario begünstigen und sollte daher mit Code-Snippets vermieden werden.

Vorsichtig: Je nach Theme, verwendete Plugins oder selbstgeschriebene Erweiterungen können die Code-Snippets bestimmte Funktionen stören. Im Zweifelsfall sollte zumindest die PHP-Ausführung im Unterordner »/wp-content/uploads« deaktiviert werden.

7.1 Apache

# Bis einschließlich Apache 2.3
# Disable direct access of any *.php files in /wp_content folder
<FilesMatch \.php$>
   Order deny,allow
   Deny from all
</FilesMatch>

# Ab Apache 2.4
# Disable direct access of any *.php files in /wp_content folder
<FilesMatch \.php$>
   Require all denied
</FilesMatch>

Die Modifikation ist in der .htaccess Datei im »/wp-content« von WordPress durchzuführen.

# Bis einschließlich Apache 2.3
# Disable direct access of any *.php files in /wp_includes folder
<FilesMatch (?<!wp-tinymce)\.php$>
   Order deny,allow
   Deny from all
</FilesMatch>

# Ab Apache 2.4
# Disable direct access of any *.php files in /wp_includes folder
<FilesMatch (?<!wp-tinymce)\.php$>
   Require all denied
</FilesMatch>

Die Modifikation ist in der .htaccess Datei im »/wp-includes« von WordPress durchzuführen.

Falls die Anpassung aufgrund von Plugins oder Modifikationen nicht funktioniert, dann legt zumindest in »/wp-content/uploads« eine .htaccess Datei mit folgendem Inhalt an:

# Bis einschließlich Apache 2.3
# Disable direct access of any *.php files in /wp_content/uploads folder
<FilesMatch \.php$>
   Order deny,allow
   Deny from all
</FilesMatch>

# Ab Apache 2.4
# Disable direct access of any *.php files in /wp_content/uploads folder
<FilesMatch \.php$>
   Require all denied
</FilesMatch>

Wie deaktiviere ich die XML-RPC-Schnittstelle in WordPress?

Warum die XML-RPC-Schnittstelle deaktivieren?Die XML-RPC Schnittstelle wird von WordPress für verschiedene Zwecke genutzt, zum Beispiel für Pingbacks und zur Kommunikation mit externen Diensten oder Smartphone-Apps. Doch nicht jeder WordPress-Nutzer verwendet diese Dienste – so bleibt die XML-RPC-Schnittstelle bei den meisten WordPress-Installationen ungenutzt und stellt stattdessen sowohl ein Sicherheitsrisiko als auch eine Performance-Bremse dar.

Seit der WordPress-Version 3.5 ist die XML-RPC-Schnittstelle standardmässig aktiviert. Um sie zu deaktivieren sind einige kleine Kniffe nötig, da sich die Schnittstelle nicht direkt über das WordPress-Backend deaktivieren lässt. Bevor Sie die XML-RPC-Schnittstelle deaktieren, sollten Sie prüfen, ob auch wirklich kein Dienst, der für Ihre Webseite wichtig ist, die Schnittstelle benutzt.

So deaktivieren Sie die XML-RPC-Schnittstelle

Zunächst deaktivieren Sie XML-RPC direkt für WordPress, indem Sie folgenden Code in die „functions.php“ Ihres WordPress-Themes einfügen:

add_filter( 'xmlrpc_enabled', '__return_false' );

Der obige Code deaktiviert XML-RPC allerdings nur in WordPress selbst. im HTTP-Header Ihrer Webseite ist die Schnittstelle (wahrscheinlich) nach wie vor sichtbar – was es Hackern, Spammern und Bots ermöglicht, Informationen abzufragen, die gar nicht dafür gedacht sind.

So entfernen Sie XML-RPC aus dem HTTP-Header

Ob XML-RPC noch im HTTP-Header Ihrer Webseite auftaucht, können Sie ganz einfach prüfen, indem Sie Ihre Webseite mit einem Tool wie zum Beispiel Redbot aufrufen. Geben Sie Ihre URL ein und schauen prüfen Sie, welche Informationen im HTTP-Header angezeigt werden. Wenn eine der Zeilen „X-Pingback und xmlrpc.php“ enthält, wissen Sie, dass XML-RPC noch nicht deaktiviert ist.

Um XML-RPC auch aus dem HTTP-Header zu entfernen, fügen noch folgenden Code zur „functions.php“ in Ihrem WordPress-Theme hinzu.

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

So wird der direkte Pfad zur XML-RPC-Schnittstelle verborgen bzw. geblockt.

Abschließend: Performance verbessern

Um nun noch leicht die Performance Ihrer Webseite zu verbessern, können Sie folgenden Code in die .htaccess-Datei Ihrer WordPress-Installation einfügen:

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

Damit wird verhindert, dass WordPress intern auf die für die XML-RPC zuständige Datei zugreifen kann und reduziert somit die Zahl unnötiger Dateizugriffe.

WordPress-Tipps zu Sicherheit und Geschwindigkeit

Grundsätzlich gilt: alles, was Sie in Ihrer WordPress-Installation nicht benötigen, sollten Sie auch entfernen oder deaktivieren. Je mehr Traffic Ihre Webseite hat, desto wichtiger ist es, dass nur die nötigsten Komponenten verwendet werden. So lädt Ihre Seite für Ihre Besucher immer mit maximaler Geschwindigkeit und die halten zugleich Angreifer und Spam-Bots ab, indem Sie diesen möglichst wenige Angriffspunkte bieten.