Webseite schützen

Aktualisiert am 20.11.2023 Lesedauer 1 - 2 Min.

Konzeptionell sind die mit  OSE  erzeugen Seiten aus sich heraus „sicher“. Angriffspunkte sind Eingabemöglichkeiten, über die „böser Code“ eingeschleust werden könnte. Daher müssen Eingabefelder mit entsprechenden Funktionen gegen Code-Injection geschützt werden.

Die allgemeine Angriffsfläche lässt sich äußerst klein halten, indem eine .htaccess-Datei im Wurzelverzeichnis der Site alles verbietet, was Webseiten-Hijacker typischerweise für einen (für sie) nützlichen Angriff brauchen: Kommunikation mit „wo anders“.

Die nachfolgende .htaccess verriegelt die Webseite weitestgehend:

  • Es werden eigene Fehlerdokumente verwendet. Das kann – abhängig vom Hosting-Konzept der Seite – eine Anpassung für Fehlermeldungen erfordern.
    Bei PLESK-verwalteten Domains muss dafür eventuell „ProxyErrorOverride on“ explizit gesetzt werden, was häufig nur der Dienstleister kann.
  • Datenverarbeitung ist nur für auf dem Webserver verfügbare Daten zugelassen. 

Ausschließlich lokale Zugriffe haben den positiven Effekt, dass die Seiten schneller laden.

  • In Seiten eingebettete Scripte werden blockiert, inklusive „onClick“ auf Links, womit sich Code einschleusen ließe.
  • Verwendete Fonts müssen lokal1 vorhanden sein, ein Link im Style-Sheet zu Google wird blockiert.
  • Einbetten von YouTube-Videos erfordert entsprechende Freigaben.
    Eine einfache Abhilfe ist ein mit der externen Quelle verlinkter Screenshot – oder ein lokal gehostetes Video.
  • Das Einbetten kleiner Bilder als Inline-Image ist erlaubt2.
  • Damit das Modul ishow und die Formatierung von Tabellen funktionieren kann, wird eingebettetes CSS zugelassen3.
  • Die Anzeige von SVG wird freigeschaltet. Das ist bei einigen Servern kein Standard4

Die Ausnahmen sind theoretische Einfallstore:

  • Der Schadcode muss sich dafür im Quelltext der Seite befinden, die vom eigenen Server geladen wird.
  • Dafür wären Datenänderungen auf dem Server erforderlich.
ABER:

Sobald das für unberechtigte Dritte möglich ist, ist alles andere sowieso egal. Berechtigte sollten verwendeten Code dementsprechend sorgfältig prüfen.

  • <em>.php-Extenders am Dateiende werden „abgeschnitten“, in Links innerhalb der Seite und „von außen“ werden sie damit überflüssig
  • Fehler werden auf „error.php“ umgeleitet
  • Zugriffe auf „sitemap.xml“ führen zur erzeugenden PHP-Datei
  • Es werden Cache-Zeiten für verschiedene Dateitypen festgelegt.

Diese .htaccess ist ein unverbindlicher Vorschlag.

Ob sie im Einzelfall für den gewünschten Zweck geeignet ist, das erwünschte Sicherheitsniveau gewährleistet oder weitere Schutzmaßnahmen erforderlich sind, liegt in der Verantwortung des Nutzers.

Die Bereitstellung dieser Datei erfolgt

OHNE GEWÄHR.

VERWENDUNG AUF EIGENE GEFAHR.

Beispiel .htaccess-Datei

Stand dieser Konfiguration: 20.09.2021

ErrorDocument 400 /err/400.html
ErrorDocument 401 
/err/401.html
ErrorDocument 403 
/err/403.html
ErrorDocument 404 
/err/404.html
ErrorDocument 500 
/err/500.html
ErrorDocument 503 
/err/503.html

<Files .htaccess>  
Order Allow,Deny
Deny from All
</Files>

# disable directory browsing
Options -Indexes 

<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000; includeSubdomains"
Header set Referrer-Policy "no-referrer"
Header always unset X-Powered-By
Header always set X
-Frame-Options "DENY"
Header always set X-Xss-Protection "1; mode=block"
Header always set X-Content-Type-Options "nosniff"
Header set Content-Security-Policy "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-ancestors 'none'; font-src 'self';"
</IfModule>

<
IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase 
/
RewriteRule sitemap.xml sitemap.php [L]

# Nur PHP-Endung weg
# Kein Ordner
 
RewriteCond %{REQUEST_FILENAME} !-d   
# ungültier Dateiname (aka „kein PHP Extender“)
RewriteCond %{REQUEST_FILENAME} !-f   
# Extender php anhängen
RewriteRule ^([^\.]+)$ $1.php [NC,L]  

</
IfModule>

# BEGIN GZIP
<ifmodule mod_deflate.c>
AddOutputFilterByType DEFLATE text/text x-httpd-php text/html text/plain text/xml text/css application/x-javascript application/javascript
</ifmodule>
# END GZIP


<IfModule mod_expires.c>
ExpiresActive on
AddType font
/woff2 .woff2
AddType font
/woff .woff
AddType image
/svg+xml svg svgz
AddEncoding gzip svgz
ExpiresByType text
/css "access plus 1 hours"
ExpiresByType text/javascript "access plus 1 hours"
ExpiresByType image/x-icon "access plus 1 days"
ExpiresByType image/ico "access plus 1 days"
ExpiresByType image/webp "access plus 1 days"
ExpiresByType image/svg+xml "access plus 1 days"
ExpiresByType image/jpg "access plus 1 days"
ExpiresByType image/jpeg "access plus 1 days"
ExpiresByType image/gif "access plus 1 days"
ExpiresByType image/png "access plus 1 days"
ExpiresByType application/pdf "access plus 1 days"
ExpiresByType font/woff2  "access plus 1 year"
ExpiresByType application/font-woff2  "access plus 7 days"
ExpiresByType application/x-font-woff2  "access plus 7 days"
ExpiresByType font/woff  "access plus 7 days"
ExpiresByType application/font-woff  "access plus 7 days"
ExpiresByType application/x-font-woff  "access plus 7 days"
ExpiresByType application/x-javascript "access plus 7 days"
ExpiresByType text/javascript "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
</IfModule>

1Lokale Fonts zulassen:
Header set Content-Security-Policy → font-src 'self';

2Eingebettete Bilder zulassen:
Header set Content-Security-Policy → img-src 'self' data:;

3Eingebettetes CSS zulassen:
Header set Content-Security-Policy → style-src 'self' 'unsafe-inline';

4SVG-Bilder rendern:
→ AddType image/svg+xml svg svgz
→ AddEncoding gzip svgz