Auch wenn ich keinen Traffic benötige, gefällt mir der Aufruf bei Traffic-Gefahr (mit der Hoffnung, dass einige How-Tos ins Board wandern) und wenn man sich privat mal wieder mit Wordpress beschäftigt...
In dieser Übersicht möchte ich nicht beschreiben, wie man Seiten oder Beiträge erstellt, sondern welche Online-Tests sinnvoll sind, was man bzgl. Sicherheit aufpassen sollte usw. Der Plan ist, dass noch mehr Beiträge von mir kommen und ich würde mich freuen, wenn sich auch noch andere beteiligen.
Als Einstieg eignet sich übrigens der Hardening WordPress Guide von Wordpress.
Eigener Rechner
Natürlich muss dein Rechner, mit dem du auf das Backend zugreifen willst, möglichst sicher sein. Bei öffentlichen Wlans lieber VPN benutzen.
Aktuell bleiben
Newsletter von WPScan Vulnerability Database oder das Security Archiv von Wordpress regelmäßig lesen.
Zusätzlich sollte man sich auf die Developer Mailinglisten setzen, um mitzubekommen, ob Plugins und Themes gewartet werden. Externe Teile der Wordpress Installation sind Angriffsvektor Nr 1!
Aktualisieren
Allgemein sollten Wordpress und Plugins immer aktuell sein. Sind Plugins veraltet, sollten diese ersetzt werden. Unnötige Plugins gehören entfernt, um die Angriffsfläche zu verringern. Deaktivieren reicht übrigens nicht!
Themes sollten ebenfalls immer aktuell sein - außer man verändert sie.
Themes
Bei der Auswahl des Themes kann man schon darauf achten, dass es aktuell ist, responsive Design verwendet und dass es möglichst sicher ist. Letzteres ist schwieriger zu testen, außer man ist selbst gut im Code Review.
Habt ihr ein Theme ausgewählt, könnt ihr es anpassen. Deinstalliert möglichst alle anderen installierten Themes, um ebenfalls die Angriffsfläche zu verringern. Bei manchen lustigen Wordpressfehlern hilft es auf ein anderes Theme zu wechseln, wodurch ich immer noch ein weiteres installiert habe. Wer wenig bastelt, benötigt es nicht.
Themes anpassen: mit zusätzlichem CSS kann man das Design (Farbe, Schriftart und ähnliches) in den Themes anpassen. Sind größere Anpassungen nötig, damit ihr zufrieden seid, könnt ihr entweder im Theme selbst schreiben (und dann nicht mehr updaten, da sonst die Änderungen alle weg sind) oder ein Child-Theme anlegen. Letzteres hat bei mir nie so wirklich geklappt.
Wer es wie ich nicht geschafft hat, ein Childtheme zu erstellen und nicht in Versuchung geraten will, das Theme zu aktualisieren, kann mit diesem Snippet innerhalb von functions.php es schaffen, dass Theme-Updates gar nicht mehr angezeigt werden. Aber Achtung, Updates bzgl. Sicherheit solltet ihr trotzdem irgendwie nachziehen können! Ein nettes Tutorial, was ich leider erst jetzt kennen gelernt habe, ist Andreas Hecht Use Child Theme.
[src=php]remove_action( 'load-update-core.php', 'wp_update_themes' );
add_filter( 'pre_site_transient_update_themes', create_function( '$a', "return null;" ) );
wp_clear_scheduled_hook( 'mng_17_update_themes' );[/src]
Plugins
Überlegt euch gut, welche Plugins ihr installiert, da auch Malware oder einfach fehlerreicher Code dabei sein kann. Je mehr Plugins, desto mehr Bugs können auch dabei sein.
Es gibt ziemlich viele Security Plugins, die verschiedene Probleme lösen sollen: Prävention, Detektion, Auditing und Zusatzfunktionalitäten.
Website Firewalls, Online Scanner, Application Scanner und File Integrity Monitoring sind wohl die üblichsten Plugin-Typen.
Persönliche Erfahrung: Firewall ist nett, aber kann die Site auch ziemlich verlangsamen. File Integrity Monitoring kann man sich selbst basteln und es gibt auch viel Schrott.
Security Plugins haben, wie alle Plugins, genauso viele Berechtigungen wie Wordpress Core (Designfehler meiner Meinung nach). Also Dokumentation und Bewertungen lesen und wenns geht evtl. auch den Code anschauen.
Benutzer
Verwende möglichst nicht den Benutzernamen admin und wähle starke Passwörter. Auch kann man den Benutzern unterschiedliche Berechtigungen zuweisen, also einen Admin-Account und einen Redaktionsaccount z.B.
Wer mehrere Wordpress-Installationen betreibt, sollte die Datenbanken voneinander trennen und unterschiedliche Identitäten die Datenbank verwalten lassen, damit bei einem Angriff nur eine Wordpress-Installation betroffen ist und nicht gleich mehrere.
Backups
Zieht regelmäßig (täglich) ein Backup der Datenbank und von Wordpress. Entweder könnt ihr das bei eurem Hoster einstellen (wenn ihr im vertraut), installiert ein Plugin oder habt ein passendes Script.
Ach ja, Backups testen soll nicht schaden, nicht dass man erst dann merkt, dass das Backup nicht funkioniert, wenn man es dringend braucht.
MW, könntest du vielleicht deines herzeigen? Soweit ich das sehe ist es besser als meine Lösung.
Logging
Logs können ebenfalls praktisch sein, um nicht autorisierte Änderungen an Dateien zu merken.
SSL
Der Sprung von HTTP auf HTTPS ist einfach im den allgemeinen Einstellungen möglich, viele Hoster bieten günstige oder kostenlose SSL-Zertifikate an. Einzig nervige ist, dass alle Bilder, die schon auf Wordpress hochgeladen und eingebunden sind, auf https umgestellt werden müssen. Auch können in Themes externe Quellen eingebunden sein, die HTTPS brechen.
Ein praktischer Scanner um zu sehen, auf welchen Seiten noch mixed content steht, ist der SSL-Scanner von Jitbit.
Falls ihr bei der Fehlerbehebung mit der Datenbank arbeiten wollt: in wp_posts sollten Links und Bilder eurer Site von http auf https geändert werden.
Falls ihr mehrere Quellen verlinkt, kann euch das Plugin Link Checker auch helfen von HTTP auf HTTPS umzustellen, da es Weiterleitungen erkennt (bei Links).
Andere Plugins sollen ebenfalls beim Umstieg helfen, aber davon habe ich keine ausprobiert.
Anschließend solltet ihr noch https erzwingen. Das habe ich in der .htaccess gemacht:
[src=apache]RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L][/src]
FTP oder besser SFTP
Über SSH und FTP/SFTP könnt ihr auf das Backend zugreifen. Macht euch mit den Möglichkeiten, die euer Hoster euch bereitstellt, bekannt. SFTP und SSH sind dabei sicherer als FTP.
.htaccess
.htaccess ist eine Konfigurationsdatei vom Apache Webserver, die man dazu verwenden kann Cachezeiten, Komprimierungen und Zugriffe zu steuern.
[src=apache]# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
</IfModule>
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl|jpeg|jpg)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresByType text/html "access plus 1 days
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType text/xml "access plus 1 seconds"
ExpiresByType application/javascript "access plus 7 days"
ExpiresDefault "access 2 days"
</IfModule>
<filesMatch "\\.(css|jpg|jpeg|png|gif|js|ico|js.gz)$">
Header set Cache-Control "max-age=604800, private"
</filesMatch>
## EXPIRES CACHING ##
<IfModule pagespeed_module>
ModPagespeed on
# using commands,filters etc
</IfModule>
# Protect readme.html File
<Files readme.html>
order allow,deny
deny from all
</Files>
# Protect license.txt file
<Files license.txt>
order allow,deny
deny from all
</Files>[/src]
Diese .htaccess habe ich im Hauptverzeichnis.
Weitere Dateien, die möglichst nicht von außen lesbar sein sollten, sind readme.html, liesmich.html, licence.md, readme.txt, readme.md, wp-config.php.
Mit [src=apache]php_flag display_errors off[/src] kann man zudem Fehlermeldungen unterdrücken, damit ein potentieller Angreifer den Serverpfad nicht in Erfahrungen bringen kann. Unnötige Dateien, wie readme, kann man übrigens auch gleich löschen.
[src=apache]<Files *.php>
deny from all
</Files>[/src]
Diese in /wp-content/uploads/ schränkt das Hochladen von php-Dateien ein, damit niemand ausführenden php-Code hochladen kann. Include-Files sollen ebenfalls geblockt werden laut Wordpress Security.
[src=apache]# Block the include-only files.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
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]
</IfModule>[/src]
Im Endeffekt:
Wer noch mehr einstellen will, findet eine etwas längliche .htaccess von Hecht Media auf Github. Längere .htaccess kann wiederum die Geschwindigkeit verlangsamen, allerdings können viele Punkte auch die Sicherheit erhöhen.
Berechtigungen
Laut dem Guide von WordPress.org sollen Ordner die Berechtigung 755 oder 750 erhalten und nicht 777. Dateien haben am besten die Berechtigungen 640 oder 644, wp-config.php 600.
Erste Zahl: Was der Owner des Files machen kann
Zweite Zahl: Was andere Nutzer in der Gruppe des Owners machen können
Dritte Zahl: Was alle anderen Nutzer (inklusive Besucher) machen können
4: Lesen
2: Schreiben
1: Ausführen
6: Lesen und Schreiben (4+2)
7: Lesen, Schreiben und Ausführen (4+2+1)
Caching und Geschwindigkeit optimieren
Oben habe ich bereits von Cache-Control in .htaccess geschrieben. Zusätzlich gibt es Caching-Plugins, wie W3 Total Cache und WP Super Cache. Beides sind die am häufigsten verwendeten Plugins, zusätzlich gibt es noch andere die Multisites unterstützen (WP Fastest Cache), schlanke wie Cachify oder Comet Cache sowie WP Rocket, was auch Lazy Loading unterstützt.
Hier kann ich ausprobieren empfehlen. In meinem Fall brachte WP Super Cache das beste Ergebnis.
Ferner gibt es Plugins, die die Seiten verkleinern, wie JCH Optimize. Manches bringt was, manches verschlechtert die Ladezeit. Einfach ausprobieren.
CDN: solange man nicht Kunden auf verschiedenen Kontinenten oder größeren Regionen hat: bringt wenig, generiert vor allem Aufwand.
Allgemein hilft es DNS Lookups, Skripte und CSS zu reduzieren sowie Bilder zu optimieren.
Obscurity bzw. aktuell weniger relevante Methoden
Diese Methoden werden mehrmals genannt, haben aber auch Nachteile oder Risiken.
Versionsnummer
Das Verschleiern der Version erschwert einen Angriff nur, wenn er gezielt ist. Ein breiter Angriff achtet häufig nicht auf die Versionsnummern, sondern wird einfach ausprobiert.
Die Version wird im wp_head durch wp_generator generiert und kann in functions.php im Theme abgestellt werden. Überlegt euch aber, was für euch sinnvoll ist und was nicht. Das ist meine Version:
[src=apache]remove_action('wp_head', 'wp_generator');[/src]
Zusätzlich kann man verwenden:
[src=apache]remove_action('wp_head', 'feed_links_extra'); //category feeds
remove_action('wp_head', 'feed_links', 2); //post and comment feeds
remove_action('wp_head', 'rsd_link'); //edituri link
remove_action('wp_head', 'wlwmanifest_link'); //windows live writer
remove_action('wp_head', 'links_rel_link'); //index link
remove_action('wp_head', 'parent_post_rel_link', 10, 0); // previous link
remove_action('wp_head', 'start_post_rel_link', 10, 0); //start link
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0); //links for adjacent posts[/src]
User Enumeration
User Enumeration ist vor allem dann wichtig, wenn mehrere Nutzer an der Seite arbeiten und die Passwörter ggf. nicht stark genug sind.
User enumeration in functions.php unterbinden:
[src=php]// block WP enum scans
if (!is_admin()) {
// default URL format
if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) die();
add_filter('redirect_canonical', 'shapeSpace_check_enum', 10, 2);
}
function shapeSpace_check_enum($redirect, $request) {
// permalink URL format
if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
else return $redirect;
}[/src]
Alternativ User Enumeration in .htaccess blockieren
[src=apache]# Block User ID Phishing Requests
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^author=([0-9]*)
RewriteRule .* http://example.com/? [L,R=302]
</IfModule>[/src]
XML-RPC
Die XML-RPC-Schnittstelle ist seit Version 3.5 standardmäßig aktiviert und kann für Brute-Force-Angriffe missbraucht werden. Manche Plugins benötigen sie, daher etwas mit Vorsicht genießen, wenn man sie deaktiviert. Die Schnittstelle dient zum Verwalten von Inhalten, wie auch für Pingbacks.
[src=php]/* Disable XMLRPC */
add_filter( 'xmlrpc_enabled', '__return_false' );[/src]
Die Schnittstelle ist deaktiviert, kann aber trotzdem angefragt werden. Esoterisch kann man jetzt die Schnittstelle im Header entfernen (was man nicht sieht, greift man nicht an *hust), indem man folgendes Snippet in der functions.php einfügt:
[src=php]<?php
/* Die XMLRPC-Schnittstelle komplett abschalten */
add_filter( 'xmlrpc_enabled', '__return_false' );
/* Den HTTP-Header vom XMLRPC-Eintrag bereinigen */
add_filter( 'wp_headers', 'AH_remove_x_pingback' );
function AH_remove_x_pingback( $headers )
{
unset( $headers['X-Pingback'] );
return $headers;
}[/src]
Wichtiger ist folgender Schritt: den Zugriff über .htaccess blockieren.
[src=apache]#XML-RPC Schnittstelle abschalten
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>[/src]
Online Tests
Security Scanner: Hacker Target
Geschwindigkeit: Pingdom
Geschwindigkeit (strenger): PageSpeed Insights
Geschwindigkeit (teils komische Kriterien, wie CDN): GTmetrix
Mobilgeräte: Google Mobile Friendly
In dieser Übersicht möchte ich nicht beschreiben, wie man Seiten oder Beiträge erstellt, sondern welche Online-Tests sinnvoll sind, was man bzgl. Sicherheit aufpassen sollte usw. Der Plan ist, dass noch mehr Beiträge von mir kommen und ich würde mich freuen, wenn sich auch noch andere beteiligen.
Als Einstieg eignet sich übrigens der Hardening WordPress Guide von Wordpress.
Eigener Rechner
Natürlich muss dein Rechner, mit dem du auf das Backend zugreifen willst, möglichst sicher sein. Bei öffentlichen Wlans lieber VPN benutzen.
Aktuell bleiben
Newsletter von WPScan Vulnerability Database oder das Security Archiv von Wordpress regelmäßig lesen.
Zusätzlich sollte man sich auf die Developer Mailinglisten setzen, um mitzubekommen, ob Plugins und Themes gewartet werden. Externe Teile der Wordpress Installation sind Angriffsvektor Nr 1!
Aktualisieren
Allgemein sollten Wordpress und Plugins immer aktuell sein. Sind Plugins veraltet, sollten diese ersetzt werden. Unnötige Plugins gehören entfernt, um die Angriffsfläche zu verringern. Deaktivieren reicht übrigens nicht!
Themes sollten ebenfalls immer aktuell sein - außer man verändert sie.
Themes
Bei der Auswahl des Themes kann man schon darauf achten, dass es aktuell ist, responsive Design verwendet und dass es möglichst sicher ist. Letzteres ist schwieriger zu testen, außer man ist selbst gut im Code Review.
Habt ihr ein Theme ausgewählt, könnt ihr es anpassen. Deinstalliert möglichst alle anderen installierten Themes, um ebenfalls die Angriffsfläche zu verringern. Bei manchen lustigen Wordpressfehlern hilft es auf ein anderes Theme zu wechseln, wodurch ich immer noch ein weiteres installiert habe. Wer wenig bastelt, benötigt es nicht.
Themes anpassen: mit zusätzlichem CSS kann man das Design (Farbe, Schriftart und ähnliches) in den Themes anpassen. Sind größere Anpassungen nötig, damit ihr zufrieden seid, könnt ihr entweder im Theme selbst schreiben (und dann nicht mehr updaten, da sonst die Änderungen alle weg sind) oder ein Child-Theme anlegen. Letzteres hat bei mir nie so wirklich geklappt.
Wer es wie ich nicht geschafft hat, ein Childtheme zu erstellen und nicht in Versuchung geraten will, das Theme zu aktualisieren, kann mit diesem Snippet innerhalb von functions.php es schaffen, dass Theme-Updates gar nicht mehr angezeigt werden. Aber Achtung, Updates bzgl. Sicherheit solltet ihr trotzdem irgendwie nachziehen können! Ein nettes Tutorial, was ich leider erst jetzt kennen gelernt habe, ist Andreas Hecht Use Child Theme.
[src=php]remove_action( 'load-update-core.php', 'wp_update_themes' );
add_filter( 'pre_site_transient_update_themes', create_function( '$a', "return null;" ) );
wp_clear_scheduled_hook( 'mng_17_update_themes' );[/src]
Plugins
Überlegt euch gut, welche Plugins ihr installiert, da auch Malware oder einfach fehlerreicher Code dabei sein kann. Je mehr Plugins, desto mehr Bugs können auch dabei sein.
Es gibt ziemlich viele Security Plugins, die verschiedene Probleme lösen sollen: Prävention, Detektion, Auditing und Zusatzfunktionalitäten.
Website Firewalls, Online Scanner, Application Scanner und File Integrity Monitoring sind wohl die üblichsten Plugin-Typen.
Persönliche Erfahrung: Firewall ist nett, aber kann die Site auch ziemlich verlangsamen. File Integrity Monitoring kann man sich selbst basteln und es gibt auch viel Schrott.
Security Plugins haben, wie alle Plugins, genauso viele Berechtigungen wie Wordpress Core (Designfehler meiner Meinung nach). Also Dokumentation und Bewertungen lesen und wenns geht evtl. auch den Code anschauen.
Benutzer
Verwende möglichst nicht den Benutzernamen admin und wähle starke Passwörter. Auch kann man den Benutzern unterschiedliche Berechtigungen zuweisen, also einen Admin-Account und einen Redaktionsaccount z.B.
Wer mehrere Wordpress-Installationen betreibt, sollte die Datenbanken voneinander trennen und unterschiedliche Identitäten die Datenbank verwalten lassen, damit bei einem Angriff nur eine Wordpress-Installation betroffen ist und nicht gleich mehrere.
Backups
Zieht regelmäßig (täglich) ein Backup der Datenbank und von Wordpress. Entweder könnt ihr das bei eurem Hoster einstellen (wenn ihr im vertraut), installiert ein Plugin oder habt ein passendes Script.
Ach ja, Backups testen soll nicht schaden, nicht dass man erst dann merkt, dass das Backup nicht funkioniert, wenn man es dringend braucht.
MW, könntest du vielleicht deines herzeigen? Soweit ich das sehe ist es besser als meine Lösung.
Logging
Logs können ebenfalls praktisch sein, um nicht autorisierte Änderungen an Dateien zu merken.
SSL
Der Sprung von HTTP auf HTTPS ist einfach im den allgemeinen Einstellungen möglich, viele Hoster bieten günstige oder kostenlose SSL-Zertifikate an. Einzig nervige ist, dass alle Bilder, die schon auf Wordpress hochgeladen und eingebunden sind, auf https umgestellt werden müssen. Auch können in Themes externe Quellen eingebunden sein, die HTTPS brechen.
Ein praktischer Scanner um zu sehen, auf welchen Seiten noch mixed content steht, ist der SSL-Scanner von Jitbit.
Falls ihr bei der Fehlerbehebung mit der Datenbank arbeiten wollt: in wp_posts sollten Links und Bilder eurer Site von http auf https geändert werden.
Falls ihr mehrere Quellen verlinkt, kann euch das Plugin Link Checker auch helfen von HTTP auf HTTPS umzustellen, da es Weiterleitungen erkennt (bei Links).
Andere Plugins sollen ebenfalls beim Umstieg helfen, aber davon habe ich keine ausprobiert.
Anschließend solltet ihr noch https erzwingen. Das habe ich in der .htaccess gemacht:
[src=apache]RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L][/src]
FTP oder besser SFTP
Über SSH und FTP/SFTP könnt ihr auf das Backend zugreifen. Macht euch mit den Möglichkeiten, die euer Hoster euch bereitstellt, bekannt. SFTP und SSH sind dabei sicherer als FTP.
.htaccess
.htaccess ist eine Konfigurationsdatei vom Apache Webserver, die man dazu verwenden kann Cachezeiten, Komprimierungen und Zugriffe zu steuern.
[src=apache]# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
</IfModule>
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl|jpeg|jpg)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresByType text/html "access plus 1 days
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType text/xml "access plus 1 seconds"
ExpiresByType application/javascript "access plus 7 days"
ExpiresDefault "access 2 days"
</IfModule>
<filesMatch "\\.(css|jpg|jpeg|png|gif|js|ico|js.gz)$">
Header set Cache-Control "max-age=604800, private"
</filesMatch>
## EXPIRES CACHING ##
<IfModule pagespeed_module>
ModPagespeed on
# using commands,filters etc
</IfModule>
# Protect readme.html File
<Files readme.html>
order allow,deny
deny from all
</Files>
# Protect license.txt file
<Files license.txt>
order allow,deny
deny from all
</Files>[/src]
Diese .htaccess habe ich im Hauptverzeichnis.
- mod_gzip und mod_deflate komprimieren bestimmte Dateien und machen eure Site dadurch schneller
- mod_expires beschreibt, wie lange was gecacht werden soll
- pagespeed_module: Beschleunigung der Site
- Protect: dadurch können Zugriffe eingeschränkt werden.
Weitere Dateien, die möglichst nicht von außen lesbar sein sollten, sind readme.html, liesmich.html, licence.md, readme.txt, readme.md, wp-config.php.
Mit [src=apache]php_flag display_errors off[/src] kann man zudem Fehlermeldungen unterdrücken, damit ein potentieller Angreifer den Serverpfad nicht in Erfahrungen bringen kann. Unnötige Dateien, wie readme, kann man übrigens auch gleich löschen.
[src=apache]<Files *.php>
deny from all
</Files>[/src]
Diese in /wp-content/uploads/ schränkt das Hochladen von php-Dateien ein, damit niemand ausführenden php-Code hochladen kann. Include-Files sollen ebenfalls geblockt werden laut Wordpress Security.
[src=apache]# Block the include-only files.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
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]
</IfModule>[/src]
Im Endeffekt:
- Unnötige Dateien löschen oder Zugriff verhindern
- Lizence, readme und liesmich zumindest den Zugriff sperren
- WP-Admin: am besten Server-Seitig Passwort setzen, wodurch normale Nutzer nicht auf /wp_admin/admin-ajax.php zugreifen können.
- WP-Includes: Skripte verbieten über obriges Skript
- WP-Uploads: Skripte verbieten über eine .htaccess im entsprechenden Verzeichnis
- WP-Config: im Root Verzeichnis
Wer noch mehr einstellen will, findet eine etwas längliche .htaccess von Hecht Media auf Github. Längere .htaccess kann wiederum die Geschwindigkeit verlangsamen, allerdings können viele Punkte auch die Sicherheit erhöhen.
Berechtigungen
Laut dem Guide von WordPress.org sollen Ordner die Berechtigung 755 oder 750 erhalten und nicht 777. Dateien haben am besten die Berechtigungen 640 oder 644, wp-config.php 600.
Erste Zahl: Was der Owner des Files machen kann
Zweite Zahl: Was andere Nutzer in der Gruppe des Owners machen können
Dritte Zahl: Was alle anderen Nutzer (inklusive Besucher) machen können
4: Lesen
2: Schreiben
1: Ausführen
6: Lesen und Schreiben (4+2)
7: Lesen, Schreiben und Ausführen (4+2+1)
Caching und Geschwindigkeit optimieren
Oben habe ich bereits von Cache-Control in .htaccess geschrieben. Zusätzlich gibt es Caching-Plugins, wie W3 Total Cache und WP Super Cache. Beides sind die am häufigsten verwendeten Plugins, zusätzlich gibt es noch andere die Multisites unterstützen (WP Fastest Cache), schlanke wie Cachify oder Comet Cache sowie WP Rocket, was auch Lazy Loading unterstützt.
Hier kann ich ausprobieren empfehlen. In meinem Fall brachte WP Super Cache das beste Ergebnis.
Ferner gibt es Plugins, die die Seiten verkleinern, wie JCH Optimize. Manches bringt was, manches verschlechtert die Ladezeit. Einfach ausprobieren.
CDN: solange man nicht Kunden auf verschiedenen Kontinenten oder größeren Regionen hat: bringt wenig, generiert vor allem Aufwand.
Allgemein hilft es DNS Lookups, Skripte und CSS zu reduzieren sowie Bilder zu optimieren.
Obscurity bzw. aktuell weniger relevante Methoden
Diese Methoden werden mehrmals genannt, haben aber auch Nachteile oder Risiken.
- Login-Versuche beschränken: hilft nur bei einem einzelnen Angreifer, nicht bei Botnetzen.
- File-Editieren über Browser verbieten, sondern nur über (S)FTP erlauben: define('DISALLOW_FILE_EDIT', true) in wp-config.php. Angriffsvektor einschränken, schmälert aber die Bequemlichkeit.
- Versionsnummer, Login-Seite verstecken, User Enumeration entfernen
- XML-RPC deaktivieren, vorausgesetzt kein Plugin benötigt es
- Display-Namen in etwas anderes als die Login-Namen ändern.
- Archive deaktivieren, wie bei wp-mix beschrieben.
Versionsnummer
Das Verschleiern der Version erschwert einen Angriff nur, wenn er gezielt ist. Ein breiter Angriff achtet häufig nicht auf die Versionsnummern, sondern wird einfach ausprobiert.
Die Version wird im wp_head durch wp_generator generiert und kann in functions.php im Theme abgestellt werden. Überlegt euch aber, was für euch sinnvoll ist und was nicht. Das ist meine Version:
[src=apache]remove_action('wp_head', 'wp_generator');[/src]
Zusätzlich kann man verwenden:
[src=apache]remove_action('wp_head', 'feed_links_extra'); //category feeds
remove_action('wp_head', 'feed_links', 2); //post and comment feeds
remove_action('wp_head', 'rsd_link'); //edituri link
remove_action('wp_head', 'wlwmanifest_link'); //windows live writer
remove_action('wp_head', 'links_rel_link'); //index link
remove_action('wp_head', 'parent_post_rel_link', 10, 0); // previous link
remove_action('wp_head', 'start_post_rel_link', 10, 0); //start link
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0); //links for adjacent posts[/src]
User Enumeration
User Enumeration ist vor allem dann wichtig, wenn mehrere Nutzer an der Seite arbeiten und die Passwörter ggf. nicht stark genug sind.
User enumeration in functions.php unterbinden:
[src=php]// block WP enum scans
if (!is_admin()) {
// default URL format
if (preg_match('/author=([0-9]*)/i', $_SERVER['QUERY_STRING'])) die();
add_filter('redirect_canonical', 'shapeSpace_check_enum', 10, 2);
}
function shapeSpace_check_enum($redirect, $request) {
// permalink URL format
if (preg_match('/\?author=([0-9]*)(\/*)/i', $request)) die();
else return $redirect;
}[/src]
Alternativ User Enumeration in .htaccess blockieren
[src=apache]# Block User ID Phishing Requests
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^author=([0-9]*)
RewriteRule .* http://example.com/? [L,R=302]
</IfModule>[/src]
XML-RPC
Die XML-RPC-Schnittstelle ist seit Version 3.5 standardmäßig aktiviert und kann für Brute-Force-Angriffe missbraucht werden. Manche Plugins benötigen sie, daher etwas mit Vorsicht genießen, wenn man sie deaktiviert. Die Schnittstelle dient zum Verwalten von Inhalten, wie auch für Pingbacks.
[src=php]/* Disable XMLRPC */
add_filter( 'xmlrpc_enabled', '__return_false' );[/src]
Die Schnittstelle ist deaktiviert, kann aber trotzdem angefragt werden. Esoterisch kann man jetzt die Schnittstelle im Header entfernen (was man nicht sieht, greift man nicht an *hust), indem man folgendes Snippet in der functions.php einfügt:
[src=php]<?php
/* Die XMLRPC-Schnittstelle komplett abschalten */
add_filter( 'xmlrpc_enabled', '__return_false' );
/* Den HTTP-Header vom XMLRPC-Eintrag bereinigen */
add_filter( 'wp_headers', 'AH_remove_x_pingback' );
function AH_remove_x_pingback( $headers )
{
unset( $headers['X-Pingback'] );
return $headers;
}[/src]
Wichtiger ist folgender Schritt: den Zugriff über .htaccess blockieren.
[src=apache]#XML-RPC Schnittstelle abschalten
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>[/src]
Online Tests
Security Scanner: Hacker Target
Geschwindigkeit: Pingdom
Geschwindigkeit (strenger): PageSpeed Insights
Geschwindigkeit (teils komische Kriterien, wie CDN): GTmetrix
Mobilgeräte: Google Mobile Friendly
Zuletzt bearbeitet: