FotoTour und Technik

WordPress Sicherheit erhöhen ohne Plugins

#Update(02.10.2019): Es wurde ein neuer Befehl für das Blockieren von REST-API im function.php hinzugefügt inklusiver IP Whitelist.

#Update(19.12.2018): Es hat sich in letzter Zeit einiges geändert. Webbkoll überprüft die Webseiten jetzt genauer und da sind mir einige Lücken aufgefallen besonders im Bereich CSP(Content-Security-Policy). Dies konnte ich leider noch nicht vollständig beheben aber verbessern. Zudem habe ich eine 6G Firewall eingebaut und das Caching verbessert.

Das “.htaccess File” wurde jetzt vollständig überarbeitet.

In diesen Beitrag möchte ich euch zeigen wie ich ohne Plug-Ins die Sicherheit meiner Webseite erhöht habe, sowie die Sicherheit meiner Besucher. Am besten testet Ihr gleich eure eigene Webseite, wie sicher diese ist mit Webbkoll und an wem Ihr eure Besucher weiterleitet.

Das erste und einfachste was man tun kann ist Cookies und Verlinkungen zu vermeiden. (z.B. keine Fonts von Google usw.)
Auch wichtig ist es die Plug-Ins und Themes die nicht zwingend benötigt werden zu löschen (nicht nur deaktivieren). Ich benutze auch keine Sicherheits Plug-Ins da diese weitere Sicherheitslücken in mein System einbringen (Da man nie weiß was diese eigentlich wirklich tun). Das einzige Plug-In was ich benutze ist “Antispam Bee” um Spam Kommentare abzufangen und “No Right Click Images Plugin” um das kopieren meiner Fotos zu erschweren.

Als nächstes wenden wir uns das sichere einloggen des Admins. Dies machen wir über eine Zwei-Faktor-Authentifizierung.
Auf dieser Webseite wird erklärt wie man die “.htpasswd” erstellt die wir benötigen:
“die-netzialisten.de”

Um die weiteren Punkte für HTTP Security-Header, HTTPS, CSP werde ich über mein Config Datei erklären.

Achtung die Änderungen wurden nur auf ein Apache 2.4 Server getestet.

Als erstes bearbeiten wir die .htaccess die im Verzeichnis “/wordpress/…” liegt.

.htaccess (Stand: 10.2019)

###################################################################################
# .htaccess by RayChan
# Für WordPress 5.0 auf eine Synology Diskstation
###################################################################################
# BEGIN WordPress
 
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
 
# END WordPress
 
###################################################################################
# Umleitung HTTP zu HTTPS
###################################################################################
 
	RewriteEngine On
	RewriteCond %{HTTPS} !=on
	RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
 
 
###################################################################################
# CORS aktivieren für bestimmte Dateitypen
# Cross-Origin Resource Sharing (CORS) ist ein Mechanismus, der Webbrowsern oder auch anderen 
# Webclients Cross-Origin-Requests ermöglicht. … CORS ist ein Kompromiss zugunsten größerer Flexibilität 
# im Internet unter Berücksichtigung möglichst hoher Sicherheitsmaßnahmen.
###################################################################################
 
    <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js|gif|png|jpe?g|svg|svgz|ico|webp)$">
        Header set Access-Control-Allow-Origin "*"
 
 
 
###################################################################################
# Der Referrer Header für mehr Datenschutz
###################################################################################
## No-Referrer-Header
 
    Header set Referrer-Policy "no-referrer"
 
 
###################################################################################
# Die HTTP-Security-Header
###################################################################################
### @see https://scotthelme.co.uk/hardening-your-http-response-headers
 
## X-FRAME-OPTIONS-Header
 
    Header set X-Frame-Options "sameorigin"
 
 
## X-XSS-PROTECTION-Header
 
    Header set X-XSS-Protection "1; mode=block"
 
 
## X-Content-Type-Options-Header
 
    Header set X-Content-Type-Options "nosniff"
 
 
## Strict-Transport-Security-Header 
 
   Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;"
 
 
###################################################################################
# Content-Security-Policy (CSP)
# https://www.ceilers-news.de/serendipity/373-Schutzmassnahmen-Content-Security-Policy-gegen-XSS,-Teil-1.html
# http://www.heise.de/security/artikel/XSS-Bremse-Content-Security-Policy-1888522.html 
# +++ Muss ist noch nicht Komplett und muss umgebaut werden +++
###################################################################################
 
	Header set Content-Security-Policy "frame-ancestors; font-src 'self';frame-src 'self'; object-src 'none';"
 
 
###################################################################################
# Zwei-Faktor-Authentifizierung
###################################################################################
# Auth protect wp-login.php
 
	AuthType Basic
	AuthName "Restricted Admin-Area"
	AuthUserFile /volume3/web/wordpress/.htpasswd
   Require valid-user
 
 
###################################################################################
# | BLOCK NUISANCE REQUESTS - New in 2018  
#   https://perishablepress.com/block-nuisance-requests
# Manche Bots suchen sehr emsig nichtexistente Dateien auf Deinem Server / Webhosting und blockieren auf diese 
# Weise die Ressourcen des Hostings. Der böswillige Datenverkehr spamt zudem die Fehlerprotokolle des Servers zu, 
# sodass eigentliche Probleme durch diese Anfragen an nichtexistente Dateien kaum mehr gefunden werden.
# Comment it out, if you don't use Let's Encrypt, because Let's Encrypt ist using .well-known
# Wenn Du Let's Encrypt nutzt, kannst Du das nicht verwenden, weil Let's Encrypt .well-known nutzt.
###################################################################################
 
	RedirectMatch 403 (?i)\.php\.suspected
	RedirectMatch 403 (?i)\.(git|well-known)
	RedirectMatch 403 (?i)apple-app-site-association
	RedirectMatch 403 (?i)/autodiscover/autodiscover.xml
 
 
###################################################################################
# Sperrt Zugriffe auf Ordner und Dateien
###################################################################################
# Deaktiviert sämtliche *.php dateien im Upload Ordner
 
   Require all denied
 
 
# Sperrt Zugriff auf .hta dateien
<FilesMatch "(\.htaccess|\.htpasswd)">
	Require all denied
 
 
# Sperrt Zugriffe auf wp-config / *.txt außer robots
<FilesMatch "(^\.|wp-config\.php|(?<!robots)\.txt|(liesmich|readme)\.*)">
   Require all denied
 
 
###################################################################################
# Ausblenden des Inhaltsverzeichnisses
###################################################################################
Options -Indexes
 
###################################################################################
# Alle Fehlerhaften Seiten auf 404 umleiten
###################################################################################
ErrorDocument 404 /error404.html
 
###################################################################################
# Sperrt Zugriff auf XML-RPC
###################################################################################
<FilesMatch "xmlrpc.php">
    Require all denied
 
 
###################################################################################
# Hotlink Protection gegen Bildklau
# Das Hotlinking verhindert, dass Deine Bilder auf anderen Websites verlinkt werden können und 
# somit die Ressourcen Deines Webhostings negativ beeinflussen. Mit diesem Schutz werden Deine Bilder 
# nur dort angezeigt, wo sie es auch sollen. Auf Deiner Website. Du musst nur das Wort »domain« 
# in Zeile 6 gegen Deine Domain tauschen.
###################################################################################
 
     RewriteEngine on
     RewriteCond %{HTTP_REFERER}     !^$
     RewriteCond %{REQUEST_FILENAME} -f
     RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png)$           [NC]
     RewriteCond %{HTTP_REFERER}     !^https?://([^.]+\.)?fototour-und-technik\. [NC]
     RewriteRule \.(gif|jpe?g?|png)$                             - [F,NC,L]
 
 
###################################################################################
#Browser Cache
###################################################################################
 
	ExpiresActive On
	ExpiresDefault                                      "access plus 1 month"
 
  # CSS
    ExpiresByType text/css                              "access plus 1 year"
 
  # Data interchange
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rdf+xml                   "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"
 
    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/ld+json                   "access plus 0 seconds"
    ExpiresByType application/schema+json               "access plus 0 seconds"
    ExpiresByType application/vnd.geo+json              "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"
 
  # Favicon (cannot be renamed!) and cursor images
    ExpiresByType image/vnd.microsoft.icon              "access plus 1 week"
    ExpiresByType image/x-icon                          "access plus 1 week"
 
  # HTML - Behält die Website eine Stunde im Cache, neues wird erst nach Ablauf einer Stunde
  # angezeigt. Wenn nicht gewuenscht, bei 3600 eine Null eintragen
    ExpiresByType text/html                             "access plus 3600 seconds"
 
  # JavaScript
    ExpiresByType application/javascript                "access plus 1 year"
    ExpiresByType application/x-javascript              "access plus 1 year"
    ExpiresByType text/javascript                       "access plus 1 year"
 
  # Manifest files
    ExpiresByType application/manifest+json             "access plus 1 week"
    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"
 
  # Media files
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/bmp                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"
    ExpiresByType image/webp                            "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"
 
  # Web fonts
 
    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType font/eot                              "access plus 1 month"
 
    # OpenType
    ExpiresByType font/opentype                         "access plus 1 month"
 
    # TrueType
    ExpiresByType application/x-font-ttf                "access plus 1 month"
 
    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/x-font-woff               "access plus 1 month"
    ExpiresByType font/woff                             "access plus 1 month"
 
    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2                "access plus 1 month"
 
  # Other
    ExpiresByType text/x-cross-domain-policy            "access plus 1 week"
 
 
 
	# Insert filters / compress text, html, javascript, css, xml:
	AddOutputFilterByType DEFLATE text/plain
	AddOutputFilterByType DEFLATE text/html
	AddOutputFilterByType DEFLATE text/xml
	AddOutputFilterByType DEFLATE text/css
	AddOutputFilterByType DEFLATE text/vtt 
	AddOutputFilterByType DEFLATE text/x-component
	AddOutputFilterByType DEFLATE application/xml
	AddOutputFilterByType DEFLATE application/xhtml+xml
	AddOutputFilterByType DEFLATE application/rss+xml
	AddOutputFilterByType DEFLATE application/js
	AddOutputFilterByType DEFLATE application/javascript
	AddOutputFilterByType DEFLATE application/x-javascript
	AddOutputFilterByType DEFLATE application/x-httpd-php
	AddOutputFilterByType DEFLATE application/x-httpd-fastphp
	AddOutputFilterByType DEFLATE application/atom+xml 
	AddOutputFilterByType DEFLATE application/json
	AddOutputFilterByType DEFLATE application/ld+json 
	AddOutputFilterByType DEFLATE application/vnd.ms-fontobject 
	AddOutputFilterByType DEFLATE application/x-font-ttf
	AddOutputFilterByType DEFLATE application/font-woff2
	AddOutputFilterByType DEFLATE application/x-font-woff
	AddOutputFilterByType DEFLATE application/x-web-app-manifest+json font/woff
	AddOutputFilterByType DEFLATE font/woff 
	AddOutputFilterByType DEFLATE font/opentype
	AddOutputFilterByType DEFLATE image/svg+xml
	AddOutputFilterByType DEFLATE image/x-icon 
 
	# Exception: Images
	SetEnvIfNoCase REQUEST_URI \.(?:gif|jpg|jpeg|png|svg)$ no-gzip dont-vary
 
	# Drop problematic browsers
	BrowserMatch ^Mozilla/4 gzip-only-text/html
	BrowserMatch ^Mozilla/4\.0[678] no-gzip
	BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
 
	# Make sure proxies don't deliver the wrong content
	Header append Vary User-Agent env=!dont-vary
 
 
#Alternative caching using Apache's "mod_headers", if it's installed.
#Caching of common files - ENABLED
 
	<FilesMatch "\.(ico|pdf|flv|swf|js|css|gif|png|jpg|jpeg|txt)$">
		Header set Cache-Control "max-age=2592000, public"
 
 
 
 
	<FilesMatch "\.(js|css|xml|gz)$">
		Header append Vary Accept-Encoding
 
 
 
# Set Keep Alive Header
 
    Header set Connection keep-alive
 
 
# If your server don't support ETags deactivate with "None" (and remove header)
 
 
      Header unset ETag 
 
    FileETag None 
 
 
 
	<FilesMatch ".(js|css|xml|gz|html|woff|woff2|ttf)$">
		Header append Vary: Accept-Encoding
 
 
 
###################################################################################
# 6G - Firewal gegen die Einschleusung von Schadcode
# 6G FIREWALL/BLACKLIST - Version 2018
# @ https://perishablepress.com/6g/
###################################################################################
# 6G:[QUERY STRINGS]
 
	RewriteEngine On
	RewriteCond %{QUERY_STRING} (eval\() [NC,OR]
	RewriteCond %{QUERY_STRING} (127\.0\.0\.1) [NC,OR]
	RewriteCond %{QUERY_STRING} ([a-z0-9]{2000,}) [NC,OR]
	RewriteCond %{QUERY_STRING} (javascript:)(.*)(;) [NC,OR]
	RewriteCond %{QUERY_STRING} (base64_encode)(.*)(\() [NC,OR]
	RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|%3C)(.*)script(.*)(>|%3) [NC,OR]
	RewriteCond %{QUERY_STRING} (\\|\.\.\.|\.\./|~|`|<|>|\|) [NC,OR]
	RewriteCond %{QUERY_STRING} (boot\.ini|etc/passwd|self/environ) [NC,OR]
	RewriteCond %{QUERY_STRING} (thumbs?(_editor|open)?|tim(thumb)?)\.php [NC,OR]
	RewriteCond %{QUERY_STRING} (\'|\")(.*)(drop|insert|md5|select|union) [NC]
	RewriteRule .* - [F]
 
 
# 6G:[REQUEST METHOD]
 
	RewriteCond %{REQUEST_METHOD} ^(connect|debug|move|put|trace|track) [NC]
	RewriteRule .* - [F]
 
 
# 6G:[REFERRERS]
 
	RewriteCond %{HTTP_REFERER} ([a-z0-9]{2000,}) [NC,OR]
	RewriteCond %{HTTP_REFERER} (semalt.com|todaperfeita) [NC]
	RewriteRule .* - [F]
 
 
# 6G:[REQUEST STRINGS]
 
	RedirectMatch 403 (?i)([a-z0-9]{2000,})
	RedirectMatch 403 (?i)(https?|ftp|php):/
	RedirectMatch 403 (?i)(base64_encode)(.*)(\()
	RedirectMatch 403 (?i)(=\\\'|=\\%27|/\\\'/?)\.
	RedirectMatch 403 (?i)/(\$(\&)?|\*|\"|\.|,|&|&?)/?$
	RedirectMatch 403 (?i)(\{0\}|\(/\(|\.\.\.|\+\+\+|\\\"\\\")
	RedirectMatch 403 (?i)(~|`|<|>|:|;|,|%|\\|\s|\{|\}|\[|\]|\|)
	RedirectMatch 403 (?i)/(=|\$&|_mm|cgi-|etc/passwd|muieblack)
	RedirectMatch 403 (?i)(&pws=0|_vti_|\(null\)|\{\$itemURL\}|echo(.*)kae|etc/passwd|eval\(|self/environ)
	RedirectMatch 403 (?i)\.(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rar|rdf)$
	RedirectMatch 403 (?i)/(^$|(wp-)?config|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell)\.php
 
 
# 6G:[USER AGENTS]
 
	SetEnvIfNoCase User-Agent ([a-z0-9]{2000,}) bad_bot
	SetEnvIfNoCase User-Agent (archive.org|binlar|casper|checkpriv|choppy|clshttp|cmsworld|diavol|dotbot|extract|feedfinder|flicky|g00g1e|harvest|heritrix|httrack|kmccrew|loader|miner|nikto|nutch|planetwork|postrank|purebot|pycurl|python|seekerspider|siclab|skygrid|sqlmap|sucker|turnit|vikspider|winhttp|xxxyy|youda|zmeu|zune) bad_bot
 
	# Apache >= 2.3
 
 
			Require all Granted
			Require not env bad_bot
 
 
 
 
# 6G:[BAD IPS]

Als zweites erweitern wir die “functions.php” aus dem “/wordpress/wp-content/themes/****/…” Verzeichnis.

functions.php (Stand: 10.2019)

/* Automatische installieren von Updates */
/* add_filter( 'auto_update_plugin', '__return_true' ); */
 
/* Deaktivieren von Emoji's */
function disable_emojis() {
   remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
   remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
   remove_action( 'wp_print_styles', 'print_emoji_styles' );
   remove_action( 'admin_print_styles', 'print_emoji_styles' ); 
   remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
   remove_filter( 'comment_text_rss', 'wp_staticize_emoji' ); 
   remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
   add_filter( 'tiny_mce_plugins', 'disable_emojis_tinymce' );
}
add_action( 'init', 'disable_emojis' );
 
/* Entfernen von TinyMCE emoji plugin */
function disable_emojis_tinymce( $plugins ) {
   if ( is_array( $plugins ) ) {
      return array_diff( $plugins, array( 'wpemoji' ) );
   } else {
      return array();
   }
}
 
/* Deaktivieren der XML-RPC Schnittstelle */
add_filter( 'xmlrpc_enabled', '__return_false' );
 
/* Deaktivieren der REST API Schnittstelle */
add_action('rest_api_init', function() {
    $whitelist = ['1.1.1.1', "::1"];    /* IP Whitelist*/
 
    if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
        die('REST API is disabled.');
    }
}, 1);
 
/* HTTP-Header Eintrag entfernen */
function wps_remove_x_pingback( $headers ) {
	unset( $headers['X-Pingback'] );
	return $headers;
}
add_filter( 'wp_headers', 'wps_remove_x_pingback' );
 
/* Entfernen von XMLRPC, WLW, Generator und ShortLink tags vom Header */
remove_action('wp_head', 'rsd_link');

Wenn Ihr dies alles getan habt, könnt Ihr nochmals eure Webseite mit Webbkoll testen.

Nächster Beitrag 26 December 2018
Vorheriger Beitrag 04 December 2018

Schreibe einen Kommentar

Dein Kommentar wird vor der Veröffentlichung von mir geprüft.