Skip to main content

Secure Wordpress

Wordpress absichern, Sicherheit erhöhen und per WAF schützen

Wie lässt sich WordPress am einfachsten und effektivsten vor Hackerangriffen schützen? Zum Thema WordPress Sicherheit gibt es bereits viele umfangreiche Artikel und verschiedene Herangehensweisen, wie man WordPress absichern kann. In diesem Artikel geht es darum, mit wenig Aufwand deutlich mehr Sicherheit zu schaffen.

WordPress Sicherheit - effektive Maßnahmen für erweiterten Schutz

Um WordPress sicher zu betreiben, ist allem voran die Wartung des Systems sehr wichtig. Regelmäßige Updates, besonders das schnellstmögliche Einspielen sicherheitskritischer Updates stehen klar im Vordergrund. Es sollte immer jemand ein Auge darauf haben.

WordPress absichern - was bedeutet das eigentlich?
Bevor wir zu den erweiterten Absicherungsmaßnahmen kommen, eine Kurzzusammenfassung der Basics:

  • Starke Passwörter (Admin Konto, FTP/SSH, Datenbank, Hosting Control Panel).
  • HTTPS/SSL für die gesamte Site erzwingen.
  • So wenige Plugins und Themes wie möglich installieren (ungenutzte löschen).
    • Themes und Plugins nur aus sicheren/originalen Quellen beziehen.
  • Regelmäßige Backups (z.B. per "UpdraftPlus Backup Plugin").
  • Eine sichere Hosting Umgebung.
    • Mehrere WordPress Instanzen sollten unbedingt isoliert, unter jeweils eigenen Systemusern laufen (-> vermeidet Massenhacks).
      Einfache Hostingpakete, in denen eine Trennung nicht möglich ist, sind für das Hosting mehrerer Sites ungeeignet.
  • Sichere Endgeräte, von denen aus auf die Website zugegriffen wird.

Über diese grundlegenden Dinge hinaus haben sich die folgenden Maßnahmen für das weiterführende Hardening bewährt.

1. Die .htaccess im Hauptverzeichnis ergänzen

Die Macht der .htaccess-Datei ist in Sachen Sicherheit unübertroffen. Einzelne Dateiaufrufe lassen sich darüber sperren und sogar ganze Verzeichnisse abriegeln.
Im Stammverzeichnis kann man die .htaccess Datei wie folgt ergänzen, damit nur noch die PHP Dateien aufgerufen werden können, welche einen Direktaufruf benötigen.

# Blockiert alle *.php Aufrufe außer index.php und ausgewählte Core Dateien im Document Root. 
# Die Unterverzeichnisse (wp-admin|wp-content|wp-includes) bleiben davon unberührt.

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(wp-admin|wp-content|wp-includes)
RewriteCond %{REQUEST_URI} !^/(index|wp-login|wp-comments-post|wp-cron|wp-trackback|xmlrpc)\.php
RewriteRule ^(.*\.php)$ - [R=403,L]

2. Absicherung per .htaccess - wp-content schützen

Gerade beim sehr dynamischen und umfangreichen /wp-content Verzeichnis macht das überaus viel Sinn. Eingeschleustem PHP-Code und Backdoors wird so der Garaus gemacht.

Angenommen ein Hacker hätte unter
https://www.webseite-bereinigen.de/wp-content/plugins/akismet/wrapper.php
einen Backdoor-Code platziert, ist diese Datei bei abgesichertem wp-content Verzeichnis nicht aufrufbar (403 - Forbidden). Gleiches gilt für alle anderen Dateien, die sich in den Tiefen von wp-content befinden oder, wie auch immer, eingeschleust werden.
In der Vergangenheit gab es Angriffe auf Plugin-Sicherheitslücken, die sich allein durch die .htaccess Absicherung sogar vollständig abwehren ließen.
Siehe WP File Manager und Contact Form 7 Vulnerabilities.

Das WordPress Verzeichnis überhaupt - wp-content absichern

/wp-content/.htaccess (Inhalt anzeigen)
# Alle PHP Direktaufrufe blockieren
<FilesMatch "\.(?i:php)$">
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
</FilesMatch>


# Ausnahmen Anfang
<FilesMatch "captcha.*\.php$">
  <IfModule !mod_authz_core.c>
    Allow from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all granted
  </IfModule>
</FilesMatch>

<FilesMatch "autoptimize.*\.php$">
  <IfModule !mod_authz_core.c>
    Allow from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all granted
  </IfModule>
</FilesMatch>

<FilesMatch "css.*\.php$">
  <IfModule !mod_authz_core.c>
    Allow from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all granted
  </IfModule>
</FilesMatch>

<FilesMatch "js.*\.php$">
  <IfModule !mod_authz_core.c>
    Allow from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all granted
  </IfModule>
</FilesMatch>

<FilesMatch "securimage.*\.php$">
  <IfModule !mod_authz_core.c>
    Allow from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all granted
  </IfModule>
</FilesMatch>

<FilesMatch "form.*\.php$">
  <IfModule !mod_authz_core.c>
    Allow from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all granted
  </IfModule>
</FilesMatch>

<FilesMatch "trp-ajax.*\.php$"> <IfModule !mod_authz_core.c> Allow from all </IfModule> <IfModule mod_authz_core.c> Require all granted </IfModule> </FilesMatch> # Ausnahmen Ende

Die .htaccess Anweisungen können einfach in eine neu erstellte oder unter /wp-content/.htaccess bereits bestehende Datei kopiert werden. In sehr seltenen Fällen sind weitere Ausnahmen nötig. Falls hier etwas noch nicht erfasst sein sollte, bitte die Kommentar Funktion unten nutzen.

Upload-Ordner schützen

Auch der /wp-content/uploads Ordner kann noch mal eigenständig mit einer .htaccess Datei geschützt werden. PHP Dateien haben darin grundsätzlich nichts zu suchen - daher sollte man alle .php Aufrufe sperren. Die /wp-content/.htaccess deckt zwar auch schon das uploads Verzeichnis ab - fall diese mal abhanden kommen sollte (versehentlich gelöscht wird), kann dieser doppelte Schutz jedoch nicht schaden.

/wp-content/uploads/.htaccess (Inhalt anzeigen)
# Alle PHP Aufrufe blockieren
<FilesMatch "\.(?i:php)$">
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
</FilesMatch>

Beispielkonfiguration .htaccess

.htaccess (Inhalt anzeigen)
# BEGIN LSCACHE
# END LSCACHE
# BEGIN NON_LSCACHE
# END NON_LSCACHE
#####
##### OLAF LEMBKE - Harden Wordpress
#####
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(wp-admin|wp-content|wp-includes)
RewriteCond %{REQUEST_URI} !^/(index|wp-login|wp-comments-post|wp-cron|wp-trackback|xmlrpc)\.php
RewriteRule ^(.*\.php)$ - [R=403,L]
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
<files wp-config.php>
   order allow,deny
   deny from all
</files>
#####
##### OLAF LEMBKE - Harden Wordpress
#####
# BEGIN WordPress
# Die Anweisungen (Zeilen) zwischen BEGIN WordPress und END WordPress sind
# dynamisch generiert und sollten nur über WordPress-Filter geändert werden.
# Alle Anderungen an den Anweisungen zwischen diesen Markierungen werden Überschrieben.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

3. Nginx Konfiguration für den wp-content Schutz (Beispiel Plesk)

Das .htaccess Konzept wird nur vom Apache Webserver unterstützt. Die Nginx Konfiguration lässt sich leider nur bei wenigen Hostern anpassen.

Da Nginx inzwischen auch sehr verbreitet ist, hier eine Beispiel Konfiguration für Hosting Umgebungen, die mit dem Plesk Control Panel verwaltet werden. Die Konfiguration wird im Feld "Zusätzliche nginx-Anweisungen" in den "Einstellungen für Apache & nginx" der Domain platziert. example.com muss durch die entsprechende Domain ersetzt werden.

Nginx Plesk Konfiguration (Inhalt anzeigen)
location /wp-content/ {

  # Ausnahmen
  location ~ captcha.*\.php$ {
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass "unix:///var/www/vhosts/system/example.com/php-fpm.sock";
    include /etc/nginx/fastcgi_params;
  }
  location ~ autoptimize.*\.php$ {
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass "unix:///var/www/vhosts/system/example.com/php-fpm.sock";
    include /etc/nginx/fastcgi_params;
  }
  location ~ css.*\.php$ {
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass "unix:///var/www/vhosts/system/example.com/php-fpm.sock";
    include /etc/nginx/fastcgi_params;
  }
  location ~ js.*\.php$ {
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass "unix:///var/www/vhosts/system/example.com/php-fpm.sock";
    include /etc/nginx/fastcgi_params;
  }
  location ~ securimage.*\.php$ {
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass "unix:///var/www/vhosts/system/example.com/php-fpm.sock";
    include /etc/nginx/fastcgi_params;
  }
  location ~ form.*\.php$ {
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass "unix:///var/www/vhosts/system/example.com/php-fpm.sock";
    include /etc/nginx/fastcgi_params;
  }

  # Alle anderen PHP Aufrufe blockieren
  location ~ \.php$ {
    deny all;
  }

}

4. WordPress mit einer Firewall absichern (NinjaFirewall)

Als hochwirksame und performante Firewall ist das Plugin "NinjaFirewall" zu empfehlen. Entgegen anderer Lösungen gibt es hier keine datenschutzrechtlichen Bedenken - die Firewall telefoniert nicht nach Hause. Zudem ist die NinjaFirewall eine der performantesten Firewalls, da sie die Datenbank nicht mit Logeinträgen befeuert, wie z.B. Wordfence.

Neue Sicherheitsregeln werden allen Usern gratis zur Verfügung gestellt. Standardmäßig wird stündlich gecheckt, ob es Updates gibt, die vor neuartigen Hacks schützen. Ein weiteres nützliches Feature sind die E-Mail Benachrichtigungen bei ausstehenden Sicherheitsupdates.

Anleitung: Einrichtung und Konfiguration der NinjaFirewall

  1. Plugin -> Installieren und aktivieren - "NinjaFirewall (WP Edition) – Advanced Security Plugin and Firewall" lautet der vollständige Name.
  2. Unter NinjaFirewall -> Dashboard  den Button [Activate Full WAF mode] klicken.
    Die Installation mit den vorgeschlagenen Einstellungen abschließen.
  3. Eine .user.ini wird im Hauptverzeichnis erstellt. Nach wenigen Minuten wird im NF Dashboard "NinjaFirewall is running in Full WAF mode" vermeldet.
  4. Unter dem Punkt "Firewall Options" kann nun eine Konfigurationsdatei importiert werden.

Eine optimale Config-Vorlage mit einem sparsameren Benachrichtigungsmail-Setup (nur sicherheitskritische Events) kann hier heruntergeladen werden:

© 2024 Olaf Lembke. All rights reserved.